From 5f85b0f5020c18f46a7fc4364d11205d90e4e5dd Mon Sep 17 00:00:00 2001 From: Amaury Zarzelli Date: Fri, 13 Sep 2024 12:21:33 +0200 Subject: [PATCH] feat(ls)(dsfr): contextual menu + all width in mobile mode (#165) --- package.json | 2 +- ...ol-layerswitcher-modules-dsfr-default.html | 5 +- .../LayerSwitcher/DSFRlayerSwitcherStyle.css | 114 +++++++++++++++++- .../LayerSwitcher/img/dsfr/context.svg | 3 + .../LayerSwitcher/LayerSwitcherDOM.js | 73 +++++++++-- 5 files changed, 183 insertions(+), 14 deletions(-) create mode 100644 src/packages/CSS/Controls/LayerSwitcher/img/dsfr/context.svg diff --git a/package.json b/package.json index 3d2e61cb9..808703713 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "geopf-extensions-openlayers", "description": "French Geoportal Extensions for OpenLayers libraries", - "version": "1.0.0-beta.0-163", + "version": "1.0.0-beta.0-165", "date": "06/09/2024", "module": "src/index.js", "directories": {}, diff --git a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-default.html b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-default.html index 447aac419..30433e686 100644 --- a/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-default.html +++ b/samples-src/pages/tests/LayerSwitcher/pages-ol-layerswitcher-modules-dsfr-default.html @@ -1,7 +1,7 @@ {{#extend "ol-sample-modules-dsfr-layout"}} {{#content "vendor"}} - + @@ -53,7 +53,8 @@

Ajout du gestionnaire de couches avec les options par défaut

var layerSwitcher = new ol.control.LayerSwitcher({ options :{ - position: 'top-right' + position: 'top-right', + panel: true, } }); map.addControl(layerSwitcher); diff --git a/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css b/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css index 6e32cf972..c984fe4ca 100644 --- a/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css +++ b/src/packages/CSS/Controls/LayerSwitcher/DSFRlayerSwitcherStyle.css @@ -170,10 +170,6 @@ div[id^=GPadvancedTools_ID_] { } .gpf-btn-icon-ls-info { - background-image: url("img/dsfr/info.svg"); - background-repeat: no-repeat; - background-size: auto auto; - background-position: center center; box-shadow: none; } @@ -222,3 +218,113 @@ div[id^=GPlayerInfoContent] { width: 350px; } +.gpf-btn-icon-close.GPlayersPanelClose { + top: 0; + right: 0; +} + +.gpf-btn-icon-close.GPlayersPanelClose::after { + margin-left: -0.125rem; +} + +/* menu contextuel (mobile) */ +.GPlayerAdvancedToolsContextual { + display: none; +} + +.GPlayerAdvancedToolsContextual::after { + -webkit-mask: url("./img/dsfr/context.svg") center no-repeat; + mask: url("./img/dsfr/context.svg") center no-repeat; +} + +.GPlayerAdvancedToolsContextual[aria-pressed="true"] { + background-color: var(--hover-tint); + overflow: visible; +} + +.GPlayerSwitcher_layer:has(.GPlayerAdvancedToolsContextual[aria-pressed="true"]) { + overflow: visible; +} + +[id^=GPlayersList-] .GPpanelBody:has(.GPlayerAdvancedToolsContextual[aria-pressed="true"]) { + overflow: visible; +} + +.GPlayerAdvancedTools:has(.GPlayerAdvancedToolsContextual[aria-pressed="true"]) { + position: relative; +} + +.GPlayerAdvancedToolsContextual + div { + display: none; + flex-direction: column; + flex-wrap: wrap; + font-size: 13px; + z-index: 12; + background-color: var(--background-overlap-grey); + border-radius: 6px; + box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.15); + padding: 14px 6px; + gap: 6px; +} + +.GPlayerAdvancedToolsContextual + div > button { + padding-left: 2rem; +} + +.GPlayerAdvancedToolsContextual + div > button[visibility="hidden"] { + display: none; +} + +.GPlayerAdvancedToolsContextual + div > button::after { + mask-position: left; +} + +.GPlayerAdvancedToolsContextual[aria-pressed="true"] + div { + display: flex; + position: absolute; + right: 0; + top: calc(2.5rem + 8px); +} + +@media (max-width: 576px) { + button[id^="GPshowLayersListPicto"][aria-pressed="true"] + dialog[id^="GPlayersList"] { + width: 100vw; + } + + .position-container-top-right button[id^="GPshowLayersListPicto"][aria-pressed="true"] + dialog[id^="GPlayersList"] { + transform: translate(58px, -4px); + } + .position-container-top-left button[id^="GPshowLayersListPicto"][aria-pressed="true"] + dialog[id^="GPlayersList"] { + transform: translate(-62px, -4px); + } + .position-container-bottom-right:has(button[id^="GPshowLayersListPicto"][aria-pressed="true"]) { + top: 4px; + bottom: unset; + } + .position-container-bottom-right button[id^="GPshowLayersListPicto"][aria-pressed="true"] + dialog[id^="GPlayersList"] { + transform: translate(58px, calc(100% - 48px)); + } + .position-container-bottom-left:has(button[id^="GPshowLayersListPicto"][aria-pressed="true"] + dialog[id^="GPlayersList"]) { + top: 4px; + bottom: unset; + } + .position-container-bottom-left button[id^="GPshowLayersListPicto"][aria-pressed="true"] + dialog[id^="GPlayersList"] { + transform: translate(-62px, calc(100% - 48px)); + } + + .GPlayerAdvancedTools { + width: calc(100% + 40px); + } + + .GPlayerAdvancedTools > .GPlayerRemove, .GPlayerAdvancedTools > .GPlayerInfo, .GPlayerAdvancedTools > .GPlayerExtent { + display: none; + } + + .GPlayerAdvancedToolsContextual { + display: inline-flex; + } + + [id^=GPopacity_ID_] { + flex-grow: 0.6; + } +} \ No newline at end of file diff --git a/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/context.svg b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/context.svg new file mode 100644 index 000000000..a05b3dd10 --- /dev/null +++ b/src/packages/CSS/Controls/LayerSwitcher/img/dsfr/context.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js b/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js index 6017462a9..8b0aad035 100644 --- a/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js +++ b/src/packages/Controls/LayerSwitcher/LayerSwitcherDOM.js @@ -458,6 +458,31 @@ var LayerSwitcherDOM = { } container.appendChild(this._createAdvancedToolExtentElement(obj)); + + if (checkDsfr()) { + var btn = document.createElement("button"); + btn.className = "GPlayerAdvancedToolsContextual fr-btn gpf-btn gpf-btn--tertiary fr-btn--tertiary-no-outline"; + btn.setAttribute("aria-pressed", false); + if (btn.addEventListener) { + btn.addEventListener("click", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + }); + } else if (btn.attachEvent) { + btn.attachEvent("onclick", function (e) { + var status = (e.target.ariaPressed === "true"); + e.target.setAttribute("aria-pressed", !status); + }); + } + + var contextual = document.createElement("div"); + contextual.appendChild(this._createAdvancedToolDeleteElement(obj, true)); + contextual.appendChild(this._createAdvancedToolInformationElement(obj, true)); + contextual.appendChild(this._createAdvancedToolExtentElement(obj, true)); + + container.appendChild(btn); + container.appendChild(contextual); + } return container; }, @@ -465,15 +490,23 @@ var LayerSwitcherDOM = { * Creation de l'icone de suppression du layer (DOM) * * @param {Object} obj - options de la couche à ajouter dans le layer switcher + * @param {Boolean} contextual - est-ce que le bouton est dans le menu contextuel ? Default false * * @returns {DOMElement} container */ - _createAdvancedToolDeleteElement : function (obj) { + _createAdvancedToolDeleteElement : function (obj, contextual = false) { var button = document.createElement("button"); - button.id = this._addUID("GPremove_ID_" + obj.id); + if (!contextual) { + button.id = this._addUID("GPremove_ID_" + obj.id); + } else { + button.id = this._addUID("GPremoveContextual_ID_" + obj.id); + } button.className = "GPlayerRemove gpf-btn gpf-btn-icon gpf-btn-icon-ls-remove fr-btn fr-btn--tertiary gpf-btn--tertiary"; button.title = "Supprimer la couche"; button.layerId = obj.id; + if (contextual) { + button.innerText = "Supprimer"; + } button.setAttribute("tabindex", "0"); button.setAttribute("aria-pressed", true); button.setAttribute("type", "button"); @@ -500,23 +533,34 @@ var LayerSwitcherDOM = { * Creation de l'icone d'information du layer (DOM) * * @param {Object} obj - options de la couche à ajouter dans le layer switcher + * @param {Boolean} contextual - est-ce que le bouton est dans le menu contextuel ? Default false * * @returns {DOMElement} container */ - _createAdvancedToolInformationElement : function (obj) { + _createAdvancedToolInformationElement : function (obj, contextual = false) { // exemple : //
var btnInfo = document.createElement("button"); - btnInfo.id = this._addUID("GPinfo_ID_" + obj.id); + if (!contextual) { + btnInfo.id = this._addUID("GPinfo_ID_" + obj.id); + } else { + btnInfo.id = this._addUID("GPinfoContextual_ID_" + obj.id); + } btnInfo.className = "GPlayerInfo GPlayerInfoClosed gpf-btn gpf-btn-icon gpf-btn-icon-ls-info fr-btn fr-btn--tertiary gpf-btn--tertiary"; // hack pour garder un emplacement vide if (!obj.title || !obj.description) { btnInfo.style.opacity = "0"; btnInfo.style.visibility = "hidden"; + if (contextual) { + btnInfo.style.display = "none"; + } } btnInfo.title = "Informations/légende"; btnInfo.layerId = obj.id; + if (contextual) { + btnInfo.innerText = "Informations"; + } btnInfo.setAttribute("tabindex", "0"); btnInfo.setAttribute("aria-pressed", true); btnInfo.setAttribute("type", "button"); @@ -572,11 +616,11 @@ var LayerSwitcherDOM = { divO.className = "GPlayerOpacity fr-range fr-range--sm"; // For DSFR divO.dataset.frJsRange = "true"; - divO.style.setProperty("--progress-right", "100%"); divO.title = "Opacité"; var opacity = (typeof obj.opacity !== "undefined") ? obj.opacity : 1; opacity = Math.round(opacity * 100); + divO.style.setProperty("--progress-right", opacity + "%"); var input = document.createElement("input"); input.id = this._addUID("GPopacityValueDiv_ID_" + obj.id); @@ -640,13 +684,28 @@ var LayerSwitcherDOM = { return list; }, - _createAdvancedToolExtentElement : function (obj) { + /** + * Creation de l'icone de zoom sur extent (DOM) + * + * @param {Object} obj - options de la couche à ajouter dans le layer switcher + * @param {Boolean} contextual - est-ce que le bouton est dans le menu contextuel ? Default false + * + * @returns {DOMElement} container + */ + _createAdvancedToolExtentElement : function (obj, contextual = false) { // FIXME inactif en mode classique ! var button = document.createElement("button"); - button.id = this._addUID("GPextent_ID_" + obj.id); + if (!contextual) { + button.id = this._addUID("GPextent_ID_" + obj.id); + } else { + button.id = this._addUID("GPextentContextual_ID_" + obj.id); + } button.className = "GPelementHidden GPlayerExtent gpf-btn gpf-btn-icon gpf-btn-icon-ls-extent fr-btn fr-btn--tertiary gpf-btn--tertiary"; button.title = "Zoomer dans l'étendue"; button.layerId = obj.id; + if (contextual) { + button.innerText = "Zommer"; + } button.setAttribute("tabindex", "0"); button.setAttribute("aria-pressed", true); button.setAttribute("type", "button");