[IMP] web_editor, website: add individual Padding option for grid items
Before this commit, the "Padding" grid mode option, added in commit [1], was impacting all the grid items at the same time, which was not convenient since all these elements would have the same padding and could not be styled individually. This commit improves this option in order to modify the padding of the grid items individually. The highlight effect, added in commit [2], when changing the padding is still added. [1]: https://github.com/odoo/odoo/commit/cc406afcea7bf5846233a9f97a4a8ac5f618f3ec [2]: https://github.com/odoo/odoo/commit/f3f2c4c73ce08d3898b8c88e1ef045f7bbd1f624 task-3369695 Part-of: odoo/odoo#136683
This commit is contained in:
committed by
qsm-odoo
parent
e828683820
commit
11418cc6f0
@@ -163,23 +163,23 @@ function _placeColumns(columnEls, rowSize, rowGap, columnSize, columnGap) {
|
||||
let zIndex = 1;
|
||||
const imageColumns = []; // array of boolean telling if it is a column with only an image.
|
||||
|
||||
// Checking if all the columns have a background color to take that into
|
||||
// account when computing their size and padding (to make them look good).
|
||||
const allBackgroundColor = [...columnEls].every(columnEl => columnEl.classList.contains('o_cc'));
|
||||
|
||||
for (const columnEl of columnEls) {
|
||||
// Finding out if the images are alone in their column.
|
||||
let isImageColumn = _checkIfImageColumn(columnEl);
|
||||
const imageEl = columnEl.querySelector('img');
|
||||
// Checking if the column has a background color to take that into
|
||||
// account when computing its size and padding (to make it look good).
|
||||
const hasBackgroundColor = columnEl.classList.contains("o_cc");
|
||||
const isImageWithoutPadding = isImageColumn && !hasBackgroundColor;
|
||||
|
||||
// Placing the column.
|
||||
const style = window.getComputedStyle(columnEl);
|
||||
// Horizontal placement.
|
||||
const columnLeft = isImageColumn ? imageEl.offsetLeft : columnEl.offsetLeft;
|
||||
const columnLeft = isImageWithoutPadding ? imageEl.offsetLeft : columnEl.offsetLeft;
|
||||
// Getting the width of the column.
|
||||
const paddingLeft = parseFloat(style.paddingLeft);
|
||||
const width = isImageColumn ? parseFloat(imageEl.scrollWidth)
|
||||
: parseFloat(columnEl.scrollWidth) - (allBackgroundColor ? 0 : 2 * paddingLeft);
|
||||
const width = isImageWithoutPadding ? parseFloat(imageEl.scrollWidth)
|
||||
: parseFloat(columnEl.scrollWidth) - (hasBackgroundColor ? 0 : 2 * paddingLeft);
|
||||
let columnSpan = Math.round((width + columnGap) / (columnSize + columnGap));
|
||||
if (columnSpan < 1) {
|
||||
columnSpan = 1;
|
||||
@@ -188,16 +188,16 @@ function _placeColumns(columnEls, rowSize, rowGap, columnSize, columnGap) {
|
||||
const columnEnd = columnStart + columnSpan;
|
||||
|
||||
// Vertical placement.
|
||||
const columnTop = isImageColumn ? imageEl.offsetTop : columnEl.offsetTop;
|
||||
const columnTop = isImageWithoutPadding ? imageEl.offsetTop : columnEl.offsetTop;
|
||||
// Getting the top and bottom paddings and computing the row offset.
|
||||
const paddingTop = parseFloat(style.paddingTop);
|
||||
const paddingBottom = parseFloat(style.paddingBottom);
|
||||
const rowOffsetTop = Math.floor((paddingTop + rowGap) / (rowSize + rowGap));
|
||||
// Getting the height of the column.
|
||||
const height = isImageColumn ? parseFloat(imageEl.scrollHeight)
|
||||
: parseFloat(columnEl.scrollHeight) - (allBackgroundColor ? 0 : paddingTop + paddingBottom);
|
||||
const height = isImageWithoutPadding ? parseFloat(imageEl.scrollHeight)
|
||||
: parseFloat(columnEl.scrollHeight) - (hasBackgroundColor ? 0 : paddingTop + paddingBottom);
|
||||
const rowSpan = Math.ceil((height + rowGap) / (rowSize + rowGap));
|
||||
const rowStart = Math.round(columnTop / (rowSize + rowGap)) + 1 + (allBackgroundColor || isImageColumn ? 0 : rowOffsetTop);
|
||||
const rowStart = Math.round(columnTop / (rowSize + rowGap)) + 1 + (hasBackgroundColor || isImageWithoutPadding ? 0 : rowOffsetTop);
|
||||
const rowEnd = rowStart + rowSpan;
|
||||
|
||||
columnEl.style.gridArea = `${rowStart} / ${columnStart} / ${rowEnd} / ${columnEnd}`;
|
||||
@@ -205,10 +205,13 @@ function _placeColumns(columnEls, rowSize, rowGap, columnSize, columnGap) {
|
||||
|
||||
// Adding the grid classes.
|
||||
columnEl.classList.add('g-col-lg-' + columnSpan, 'g-height-' + rowSpan);
|
||||
|
||||
// Setting the initial z-index.
|
||||
columnEl.style.zIndex = zIndex++;
|
||||
|
||||
// Setting the paddings.
|
||||
if (hasBackgroundColor) {
|
||||
columnEl.style.setProperty("--grid-item-padding-y", `${paddingTop}px`);
|
||||
columnEl.style.setProperty("--grid-item-padding-x", `${paddingLeft}px`);
|
||||
}
|
||||
// Reload the images.
|
||||
_reloadLazyImages(columnEl);
|
||||
|
||||
@@ -217,17 +220,6 @@ function _placeColumns(columnEls, rowSize, rowGap, columnSize, columnGap) {
|
||||
imageColumns.push(isImageColumn);
|
||||
}
|
||||
|
||||
// If all the columns have a background color, set their padding to the
|
||||
// original padding of the first column.
|
||||
if (allBackgroundColor) {
|
||||
const style = window.getComputedStyle(columnEls[0]);
|
||||
const paddingY = style.paddingTop;
|
||||
const paddingX = style.paddingLeft;
|
||||
const rowEl = columnEls[0].parentNode;
|
||||
rowEl.style.setProperty('--grid-item-padding-y', paddingY);
|
||||
rowEl.style.setProperty('--grid-item-padding-x', paddingX);
|
||||
}
|
||||
|
||||
for (const [i, columnEl] of [...columnEls].entries()) {
|
||||
// Removing padding and offset classes.
|
||||
const regex = /^(pt|pb|col-|offset-)/;
|
||||
@@ -304,6 +296,8 @@ export function _convertToNormalColumn(columnEl) {
|
||||
const gridSizeClasses = columnEl.className.match(/(g-col-lg|g-height)-[0-9]+/g);
|
||||
columnEl.classList.remove("o_grid_item", "o_grid_item_image", "o_grid_item_image_contain", ...gridSizeClasses);
|
||||
columnEl.style.removeProperty("z-index");
|
||||
columnEl.style.removeProperty("--grid-item-padding-x");
|
||||
columnEl.style.removeProperty("--grid-item-padding-y");
|
||||
columnEl.style.removeProperty("grid-area");
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -5111,15 +5111,6 @@ registry.Box = SnippetOptionWidget.extend({
|
||||
|
||||
|
||||
registry.layout_column = SnippetOptionWidget.extend({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
cleanForSave() {
|
||||
// Remove the padding highlights.
|
||||
this.$target[0].querySelectorAll('.o_we_padding_highlight').forEach(highlightedEl => {
|
||||
highlightedEl._removePaddingPreview();
|
||||
});
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Options
|
||||
@@ -5266,24 +5257,6 @@ registry.layout_column = SnippetOptionWidget.extend({
|
||||
gridUtils._resizeGrid(rowEl);
|
||||
this.trigger_up('activate_snippet', {$snippet: $(newColumnEl)});
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async selectStyle(previewMode, widgetValue, params) {
|
||||
await this._super(...arguments);
|
||||
if (params.cssProperty.startsWith('--grid-item-padding')) {
|
||||
// Reset the animations.
|
||||
this._removePaddingPreview();
|
||||
void this.$target[0].offsetWidth; // Trigger a DOM reflow.
|
||||
|
||||
// Highlight the padding when changing it, by adding a pseudo-
|
||||
// element with an animated colored border inside the grid items.
|
||||
const rowEl = this.$target[0];
|
||||
rowEl.classList.add('o_we_padding_highlight');
|
||||
rowEl._removePaddingPreview = this._removePaddingPreview.bind(this);
|
||||
rowEl.addEventListener('animationend', rowEl._removePaddingPreview);
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
@@ -5381,10 +5354,18 @@ registry.layout_column = SnippetOptionWidget.extend({
|
||||
* @private
|
||||
* @param {Element} rowEl
|
||||
*/
|
||||
_toggleNormalMode(rowEl) {
|
||||
async _toggleNormalMode(rowEl) {
|
||||
// Removing the grid class
|
||||
rowEl.classList.remove('o_grid_mode');
|
||||
const columnEls = rowEl.children;
|
||||
// Removing the grid previews (if any).
|
||||
await new Promise(resolve => {
|
||||
this.trigger_up("clean_ui_request", {
|
||||
targetEl: this.$target[0].closest("section"),
|
||||
onSuccess: resolve,
|
||||
});
|
||||
});
|
||||
|
||||
for (const columnEl of columnEls) {
|
||||
// Reloading the images.
|
||||
gridUtils._reloadLazyImages(columnEl);
|
||||
@@ -5393,20 +5374,70 @@ registry.layout_column = SnippetOptionWidget.extend({
|
||||
}
|
||||
// Removing the grid properties.
|
||||
delete rowEl.dataset.rowCount;
|
||||
// Kept for compatibility.
|
||||
rowEl.style.removeProperty('--grid-item-padding-x');
|
||||
rowEl.style.removeProperty('--grid-item-padding-y');
|
||||
},
|
||||
});
|
||||
|
||||
registry.GridColumns = SnippetOptionWidget.extend({
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
cleanUI() {
|
||||
// Remove the padding highlights.
|
||||
this._removePaddingPreview();
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Options
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
async selectStyle(previewMode, widgetValue, params) {
|
||||
await this._super(...arguments);
|
||||
if (["--grid-item-padding-y", "--grid-item-padding-x"].includes(params.cssProperty)) {
|
||||
// Reset the animation.
|
||||
this._removePaddingPreview();
|
||||
void this.$target[0].offsetWidth; // Trigger a DOM reflow.
|
||||
|
||||
// Highlight the padding when changing it, by adding a pseudo-
|
||||
// element with an animated colored border inside the grid item.
|
||||
this.options.wysiwyg.odooEditor.observerUnactive("addPaddingPreview");
|
||||
this.$target[0].classList.add("o_we_padding_highlight");
|
||||
this.options.wysiwyg.odooEditor.observerActive("addPaddingPreview");
|
||||
this.removePaddingPreview = this._removePaddingPreview.bind(this);
|
||||
this.$target[0].addEventListener("animationend", this.removePaddingPreview);
|
||||
}
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_computeWidgetVisibility(widgetName, params) {
|
||||
if (["grid_padding_y_opt", "grid_padding_x_opt"].includes(widgetName)) {
|
||||
return this.$target[0].parentElement.classList.contains("o_grid_mode");
|
||||
}
|
||||
return this._super(...arguments);
|
||||
},
|
||||
/**
|
||||
* Removes the padding highlights that were added when changing the grid
|
||||
* items padding.
|
||||
* item padding.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_removePaddingPreview() {
|
||||
const rowEl = this.$target[0];
|
||||
rowEl.removeEventListener('animationend', rowEl._removePaddingPreview);
|
||||
rowEl.classList.remove('o_we_padding_highlight');
|
||||
delete rowEl._removePaddingPreview;
|
||||
this.options.wysiwyg.odooEditor.observerUnactive("removePaddingPreview");
|
||||
this.$target[0].removeEventListener("animationend", this.removePaddingPreview);
|
||||
this.$target[0].classList.remove("o_we_padding_highlight");
|
||||
delete this.removePaddingPreview;
|
||||
this.options.wysiwyg.odooEditor.observerActive("removePaddingPreview");
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -2638,7 +2638,7 @@ we-button-group.o_grid we-selection-items {
|
||||
}
|
||||
}
|
||||
|
||||
.o_we_padding_highlight > .o_grid_item {
|
||||
.o_we_padding_highlight.o_grid_item {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
|
||||
@@ -539,10 +539,6 @@
|
||||
<we-button class="o_we_bg_brand_primary o_grid" data-add-element="text" title="Text" data-name="text">Text</we-button>
|
||||
<we-button class="o_we_bg_brand_primary o_grid" data-add-element="button" title="Button" data-name="button">Button</we-button>
|
||||
</we-button-group>
|
||||
<we-row string="Padding (Y, X)">
|
||||
<we-input data-dependencies="grid_mode" data-select-style="" data-css-property="--grid-item-padding-y" data-unit="px" data-apply-to=".row"/>
|
||||
<we-input data-dependencies="grid_mode" data-select-style="" data-css-property="--grid-item-padding-x" data-unit="px" data-apply-to=".row"/>
|
||||
</we-row>
|
||||
</div>
|
||||
|
||||
<!-- Grid and columns -->
|
||||
@@ -570,10 +566,6 @@
|
||||
<we-button class="o_we_bg_brand_primary o_grid" data-add-element="text" title="Text" data-name="text">Text</we-button>
|
||||
<we-button class="o_we_bg_brand_primary o_grid" data-add-element="button" title="Button" data-name="button">Button</we-button>
|
||||
</we-button-group>
|
||||
<we-row class="o_we_sublevel_1" string="Padding (Y, X)">
|
||||
<we-input data-dependencies="grid_mode" data-select-style="" data-css-property="--grid-item-padding-y" data-unit="px" data-apply-to=".row"/>
|
||||
<we-input data-dependencies="grid_mode" data-select-style="" data-css-property="--grid-item-padding-x" data-unit="px" data-apply-to=".row"/>
|
||||
</we-row>
|
||||
</div>
|
||||
|
||||
<!-- Vertical Alignment -->
|
||||
@@ -647,6 +639,15 @@
|
||||
<t t-set="with_shapes" t-value="True"/>
|
||||
</t>
|
||||
|
||||
<!-- Grid mode columns -->
|
||||
<div data-js="GridColumns"
|
||||
data-selector=".row > div">
|
||||
<we-row string="Padding (Y, X)">
|
||||
<we-input data-select-style="" data-css-property="--grid-item-padding-y" data-unit="px" data-name="grid_padding_y_opt"/>
|
||||
<we-input data-select-style="" data-css-property="--grid-item-padding-x" data-unit="px" data-name="grid_padding_x_opt"/>
|
||||
</we-row>
|
||||
</div>
|
||||
|
||||
<!-- Border | Columns -->
|
||||
<div data-js="Box"
|
||||
data-selector="section .row > div"
|
||||
|
||||
Reference in New Issue
Block a user