From 8aaaccfcc7973142e057d0d0e89a4551e4dd773c Mon Sep 17 00:00:00 2001 From: "Robin Lejeune (role)" Date: Tue, 28 Mar 2023 15:17:15 +0000 Subject: [PATCH] [IMP] web_editor: toggle background shape on mobile Currently, all background shapes of snippets are hidden on mobile, because most of them don't look great on small screens. This commit adds a button in the website editor to toggle the shape on mobile. It remains hidden by default if added on desktop, but displayed by default if added on mobile. task-3096132 closes odoo/odoo#116958 Signed-off-by: Quentin Smetz (qsm) --- .../static/src/js/editor/snippets.options.js | 30 +++++++++++++++++-- .../static/src/scss/web_editor.frontend.scss | 2 +- .../static/src/scss/wysiwyg_snippets.scss | 5 +++- addons/web_editor/views/snippets.xml | 3 ++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/snippets.options.js b/addons/web_editor/static/src/js/editor/snippets.options.js index d7ee2e50fb7..2e698b76a8f 100644 --- a/addons/web_editor/static/src/js/editor/snippets.options.js +++ b/addons/web_editor/static/src/js/editor/snippets.options.js @@ -6953,6 +6953,16 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ flipY(previewMode, widgetValue, params) { this._flipShape(previewMode, 'y'); }, + /** + * Shows/Hides the shape on mobile. + * + * @see this.selectClass for params + */ + showOnMobile(previewMode, widgetValue, params) { + this._handlePreviewState(previewMode, () => { + return {showOnMobile: !this._getShapeData().showOnMobile}; + }); + }, //-------------------------------------------------------------------------- // Private @@ -6982,6 +6992,9 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ const hasFlipClass = this.$target.find('> .o_we_shape.o_we_flip_y').length !== 0; return hasFlipClass || this._getShapeData().flip.includes('y'); } + case 'showOnMobile': { + return this._getShapeData().showOnMobile; + } } return this._super(...arguments); }, @@ -7102,7 +7115,7 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ // Updates/removes the shape container as needed and gives it the // correct background shape const json = target.dataset.oeShapeData; - const {shape, colors, flip = [], animated = 'false'} = json ? JSON.parse(json) : {}; + const {shape, colors, flip = [], animated = 'false', showOnMobile} = json ? JSON.parse(json) : {}; let shapeContainer = target.querySelector(':scope > .o_we_shape'); if (!shape) { return this._insertShapeContainer(null); @@ -7135,6 +7148,7 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ $(shapeContainer).css('background-image', ''); $(shapeContainer).css('background-position', ''); } + shapeContainer.classList.toggle('o_shape_show_mobile', !!showOnMobile); if (previewMode === false) { this.prevShapeContainer = shapeContainer.cloneNode(true); this.prevShape = target.dataset.oeShapeData; @@ -7210,6 +7224,7 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ shape: '', colors: this._getDefaultColors($(target)), flip: [], + showOnMobile: false, }; const json = target.dataset.oeShapeData; return json ? Object.assign(defaultData, JSON.parse(json.replace(/'/g, '"'))) : defaultData; @@ -7302,12 +7317,23 @@ registry.BackgroundShape = SnippetOptionWidget.extend({ if (!shapeToSelect) { shapeToSelect = possibleShapes[1]; } + // Only show on mobile by default if toggled from mobile view + const mobileViewThreshold = MEDIAS_BREAKPOINTS[SIZES.LG].minWidth; + const isMobileView = this.$target[0].ownerDocument + .defaultView.frameElement.clientWidth < mobileViewThreshold; + const showOnMobile = isMobileView; this.trigger_up('snippet_edition_request', {exec: () => { // options for shape will only be available after _toggleShape() returned this._requestUserValueWidgets('bg_shape_opt')[0].enable(); }}); this._createShapeContainer(shapeToSelect); - return this._handlePreviewState(false, () => ({shape: shapeToSelect, colors: this._getImplicitColors(shapeToSelect)})); + return this._handlePreviewState(false, () => ( + { + shape: shapeToSelect, + colors: this._getImplicitColors(shapeToSelect), + showOnMobile, + } + )); } }, }); diff --git a/addons/web_editor/static/src/scss/web_editor.frontend.scss b/addons/web_editor/static/src/scss/web_editor.frontend.scss index c95b964d41f..a4cb68a70ee 100644 --- a/addons/web_editor/static/src/scss/web_editor.frontend.scss +++ b/addons/web_editor/static/src/scss/web_editor.frontend.scss @@ -18,7 +18,7 @@ } @include media-breakpoint-down(md) { - .o_we_shape { + .o_we_shape:not(.o_shape_show_mobile) { display: none; } } diff --git a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss index 10f3560318c..43766b754bb 100644 --- a/addons/web_editor/static/src/scss/wysiwyg_snippets.scss +++ b/addons/web_editor/static/src/scss/wysiwyg_snippets.scss @@ -1031,7 +1031,10 @@ border-right-width: ($o-we-item-spacing - 1px); } } - &:not(.o_we_so_color_palette) + we-button:not(:hover):not(.o_we_image_shape_remove) { + // Special buttons (e.g. remove/position) next to the we-select + // should be toned down. Also makes sure that only one button is + // targeted, and that should be the last one. + &:not(.o_we_so_color_palette) ~ we-button:not(:hover):not(.o_we_image_shape_remove):last-child { background: none; } diff --git a/addons/web_editor/views/snippets.xml b/addons/web_editor/views/snippets.xml index dbdbb34c374..bad5cede7f0 100644 --- a/addons/web_editor/views/snippets.xml +++ b/addons/web_editor/views/snippets.xml @@ -395,6 +395,9 @@ +