From 0b175d1a56e4fcaf239078085728fdae8016583b Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 15 Mar 2024 11:29:59 +0100 Subject: [PATCH] chore: use icon buttons where possible --- umap/static/umap/base.css | 5 +- umap/static/umap/css/icon.css | 20 ++++++-- umap/static/umap/js/modules/browser.js | 21 ++++---- umap/static/umap/js/umap.controls.js | 67 ++++++++++++++++--------- umap/static/umap/js/umap.core.js | 20 ++++++-- umap/static/umap/js/umap.importer.js | 6 ++- umap/static/umap/js/umap.js | 2 +- umap/static/umap/js/umap.layer.js | 2 +- umap/static/umap/js/umap.permissions.js | 2 +- umap/static/umap/js/umap.share.js | 6 ++- 10 files changed, 102 insertions(+), 49 deletions(-) diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index 995f95b7..456b3063 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -21,6 +21,9 @@ a { text-decoration: none; color: SeaGreen; } +button { + cursor: pointer; +} hr { clear: both; width: 100%; @@ -530,7 +533,7 @@ i.info { background-position: -150px -78px; } .umap-delete:before { - background-position: -40px -8px; + background-position: -32px -8px; } .umap-edit:before { background-position: -6px -6px; diff --git a/umap/static/umap/css/icon.css b/umap/static/umap/css/icon.css index 87257be2..39778ee1 100644 --- a/umap/static/umap/css/icon.css +++ b/umap/static/umap/css/icon.css @@ -1,8 +1,12 @@ +/* Applied on i and button elements */ .icon { background-repeat: no-repeat; display: inline-block; padding: 0 10px; vertical-align: middle; + /* Reste default style, in case we apply this class on a button element */ + border: none; + background-color: initial; } .icon-16 { background-image: url('../img/16.svg'); @@ -16,7 +20,7 @@ background-image: url('../img/16-white.svg'); } .icon-add { - background-position: -26px -30px; + background-position: -26px -24px; } .icon-back { background-position: -122px -144px; @@ -30,17 +34,27 @@ .icon-delete { background-position: -121px -49px; } +.readonly .icon-delete, +.off .icon-delete { + background-position: -121px -122px; +} .icon-drag { background-position: -72px -73px; cursor: move; - margin-right: 10px; + float: right; } .icon-eye { background-position: -49px -26px; } +.off .icon-eye { + background-position: -73px -26px; +} .icon-edit { background-position: -51px -49px; } +.off .icon-edit { + background-position: -51px -73px; +} .icon-key { background-position: -144px -121px; } @@ -91,5 +105,5 @@ background-position: -1px -49px; } .off .icon-zoom { - background-position: -25px -54px; + background-position: -25px -49px; } diff --git a/umap/static/umap/js/modules/browser.js b/umap/static/umap/js/modules/browser.js index fe1bc092..59fe52e4 100644 --- a/umap/static/umap/js/modules/browser.js +++ b/umap/static/umap/js/modules/browser.js @@ -15,18 +15,15 @@ export default class Browser { const filter = this.options.filter if (filter && !feature.matchFilter(filter, this.filterKeys)) return if (this.options.inBbox && !feature.isOnScreen(this.bounds)) return - const feature_li = DomUtil.create('li', `${feature.getClassName()} feature`), - zoom_to = DomUtil.create('i', 'icon icon-16 icon-zoom', feature_li), - edit = DomUtil.create('i', 'icon icon-16 show-on-edit icon-edit', feature_li), - del = DomUtil.create('i', 'icon icon-16 show-on-edit icon-delete', feature_li), - colorBox = DomUtil.create('i', 'icon icon-16 feature-color', feature_li), - title = DomUtil.create('span', 'feature-title', feature_li), - symbol = feature._getIconUrl + const row = DomUtil.create('li', `${feature.getClassName()} feature`) + const zoom_to = DomUtil.createButtonIcon(row, 'icon-zoom', translate('Bring feature to center')) + const edit = DomUtil.createButtonIcon(row, 'show-on-edit icon-edit', translate('Edit this feature')) + const del = DomUtil.createButtonIcon(row, 'show-on-edit icon-delete', translate('Delete this feature')) + const colorBox = DomUtil.create('i', 'icon icon-16 feature-color', row) + const title = DomUtil.create('span', 'feature-title', row) + const symbol = feature._getIconUrl ? U.Icon.prototype.formatUrl(feature._getIconUrl(), feature) : null - zoom_to.title = translate('Bring feature to center') - edit.title = translate('Edit this feature') - del.title = translate('Delete this feature') title.textContent = feature.getDisplayName() || '—' const bgcolor = feature.getDynamicOption('color') colorBox.style.backgroundColor = bgcolor @@ -56,8 +53,8 @@ export default class Browser { DomEvent.on(del, 'click', feature.confirmDelete, feature) // HOTFIX. Remove when this is released: // https://github.com/Leaflet/Leaflet/pull/9052 - DomEvent.disableClickPropagation(feature_li) - parent.appendChild(feature_li) + DomEvent.disableClickPropagation(row) + parent.appendChild(row) } datalayerId(datalayer) { diff --git a/umap/static/umap/js/umap.controls.js b/umap/static/umap/js/umap.controls.js index 8daa7e29..45ce42e3 100644 --- a/umap/static/umap/js/umap.controls.js +++ b/umap/static/umap/js/umap.controls.js @@ -561,16 +561,31 @@ U.DataLayer.include({ }, renderToolbox: function (container) { - const toggle = L.DomUtil.create('i', 'icon icon-16 icon-eye', container), - zoomTo = L.DomUtil.create('i', 'icon icon-16 icon-zoom', container), - edit = L.DomUtil.create('i', 'icon icon-16 icon-edit show-on-edit', container), - table = L.DomUtil.create('i', 'icon icon-16 icon-table show-on-edit', container), - remove = L.DomUtil.create('i', 'icon icon-16 icon-delete show-on-edit', container) - zoomTo.title = L._('Zoom to layer extent') - toggle.title = L._('Show/hide layer') - edit.title = L._('Edit') - table.title = L._('Edit properties in a table') - remove.title = L._('Delete layer') + const toggle = L.DomUtil.createButtonIcon( + container, + 'icon-eye', + L._('Show/hide layer') + ) + const zoomTo = L.DomUtil.createButtonIcon( + container, + 'icon-zoom', + L._('Zoom to layer extent') + ) + const edit = L.DomUtil.createButtonIcon( + container, + 'icon-edit show-on-edit', + L._('Edit') + ) + const table = L.DomUtil.createButtonIcon( + container, + 'icon-table show-on-edit', + L._('Edit properties in a table') + ) + const remove = L.DomUtil.createButtonIcon( + container, + 'icon-delete show-on-edit', + L._('Delete layer') + ) if (this.isReadOnly()) { L.DomUtil.addClass(container, 'readonly') } else { @@ -700,7 +715,7 @@ const ControlsMixin = { displayCaption: function () { const container = L.DomUtil.create('div', 'umap-caption') - L.DomUtil.createTitle(container, this.options.name, 'caption') + L.DomUtil.createTitle(container, this.options.name, 'icon-caption') this.permissions.addOwnerLink('h5', container) if (this.options.description) { const description = L.DomUtil.create('div', 'umap-map-description', container) @@ -929,12 +944,11 @@ const ControlsMixin = { editDatalayers: function () { if (!this.editEnabled) return const container = L.DomUtil.create('div') - L.DomUtil.createTitle(container, L._('Manage layers'), 'layers') + L.DomUtil.createTitle(container, L._('Manage layers'), 'icon-layers') const ul = L.DomUtil.create('ul', '', container) this.eachDataLayerReverse((datalayer) => { const row = L.DomUtil.create('li', 'orderable', ul) - const dragHandle = L.DomUtil.create('i', 'icon icon-16 icon-drag', row) - dragHandle.title = L._('Drag to reorder') + L.DomUtil.createIcon(row, 'icon-drag', L._('Drag to reorder')) datalayer.renderToolbox(row) const title = L.DomUtil.add('span', '', row, datalayer.options.name) L.DomUtil.classIf(row, 'off', !datalayer.isVisible()) @@ -1037,7 +1051,7 @@ U.TileLayerChooser = L.Control.extend({ openSwitcher: function (options) { const container = L.DomUtil.create('div', 'umap-tilelayer-switcher-container') - L.DomUtil.createTitle(container, L._('Change tilelayers'), 'tilelayer') + L.DomUtil.createTitle(container, L._('Change tilelayers'), 'icon-tilelayer') this._tilelayers_container = L.DomUtil.create('ul', '', container) this.buildList(options) this.map.editPanel.open({ @@ -1205,21 +1219,26 @@ U.Search = L.PhotonSearch.extend({ }, formatResult: function (feature, el) { - const self = this - const tools = L.DomUtil.create('span', 'search-result-tools', el), - zoom = L.DomUtil.create('i', 'icon icon-16 icon-zoom', tools), - edit = L.DomUtil.create('i', 'icon icon-16 icon-edit show-on-edit', tools) - zoom.title = L._('Zoom to this place') - edit.title = L._('Save this location as new feature') + const tools = L.DomUtil.create('span', 'search-result-tools', el) + const zoom = L.DomUtil.createButtonIcon( + tools, + 'icon-zoom', + L._('Zoom to this place') + ) + const edit = L.DomUtil.createButtonIcon( + tools, + 'icon-edit', + L._('Save this location as new feature') + ) // We need to use "mousedown" because Leaflet.Photon listen to mousedown // on el. L.DomEvent.on(zoom, 'mousedown', (e) => { L.DomEvent.stop(e) - self.zoomToFeature(feature) + this.zoomToFeature(feature) }) L.DomEvent.on(edit, 'mousedown', (e) => { L.DomEvent.stop(e) - const datalayer = self.map.defaultEditDataLayer() + const datalayer = this.map.defaultEditDataLayer() const layer = datalayer.geojsonToFeatures(feature) layer.isDirty = true layer.edit() @@ -1271,7 +1290,7 @@ U.SearchControl = L.Control.extend({ if (this.map.options.photonUrl) options.url = this.map.options.photonUrl const container = L.DomUtil.create('div', '') - L.DomUtil.createTitle(container, L._('Search location'), 'search') + L.DomUtil.createTitle(container, L._('Search location'), 'icon-search') const input = L.DomUtil.create('input', 'photon-input', container) const resultsContainer = L.DomUtil.create('div', 'photon-autocomplete', container) this.search = new U.Search(this.map, input, options) diff --git a/umap/static/umap/js/umap.core.js b/umap/static/umap/js/umap.core.js index c451879f..e3794e82 100644 --- a/umap/static/umap/js/umap.core.js +++ b/umap/static/umap/js/umap.core.js @@ -117,13 +117,25 @@ L.DomUtil.createLink = (className, container, content, url, target, title) => { return el } -L.DomUtil.createIcon = (parent, name) => { - L.DomUtil.create('i', `icon icon-16 icon-${name}`, parent) +L.DomUtil.createIcon = (parent, className, title, size = 16) => { + return L.DomUtil.element( + 'i', + { className: `icon icon-${size} ${className}`, title: title }, + parent + ) } -L.DomUtil.createTitle = (parent, text, icon, tag = 'h3') => { +L.DomUtil.createButtonIcon = (parent, className, title, size = 16) => { + return L.DomUtil.element( + 'button', + { className: `icon icon-${size} ${className}`, title: title }, + parent + ) +} + +L.DomUtil.createTitle = (parent, text, className, tag = 'h3') => { const title = L.DomUtil.create(tag, '', parent) - L.DomUtil.createIcon(title, icon) + L.DomUtil.createIcon(title, className) L.DomUtil.add('span', '', title, text) return title } diff --git a/umap/static/umap/js/umap.importer.js b/umap/static/umap/js/umap.importer.js index d3e85df7..ff5237b1 100644 --- a/umap/static/umap/js/umap.importer.js +++ b/umap/static/umap/js/umap.importer.js @@ -7,7 +7,11 @@ U.Importer = L.Class.extend({ build: function () { this.container = L.DomUtil.create('div', 'umap-upload') - this.title = L.DomUtil.createTitle(this.container, L._('Import data'), 'upload') + this.title = L.DomUtil.createTitle( + this.container, + L._('Import data'), + 'icon-upload' + ) this.presetBox = L.DomUtil.create('div', 'formbox', this.container) this.presetSelect = L.DomUtil.create('select', '', this.presetBox) this.fileBox = L.DomUtil.create('div', 'formbox', this.container) diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index 60b13208..a8c37e7b 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -1540,7 +1540,7 @@ U.Map = L.Map.extend({ if (!this.editEnabled) return if (this.options.editMode !== 'advanced') return const container = L.DomUtil.create('div') - L.DomUtil.createTitle(container, L._('Map advanced properties'), 'settings') + L.DomUtil.createTitle(container, L._('Map advanced properties'), 'icon-settings') this._editControls(container) this._editShapeProperties(container) this._editDefaultProperties(container) diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 93c088ce..dad7a770 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1211,7 +1211,7 @@ U.DataLayer = L.Evented.extend({ }, ], ] - L.DomUtil.createTitle(container, L._('Layer properties'), 'layers') + L.DomUtil.createTitle(container, L._('Layer properties'), 'icon-layers') let builder = new U.FormBuilder(this, metadataFields, { callback: function (e) { if (e.helper.field === 'options.type') { diff --git a/umap/static/umap/js/umap.permissions.js b/umap/static/umap/js/umap.permissions.js index 871e88fe..00a25bd2 100644 --- a/umap/static/umap/js/umap.permissions.js +++ b/umap/static/umap/js/umap.permissions.js @@ -59,7 +59,7 @@ U.MapPermissions = L.Class.extend({ }) const container = L.DomUtil.create('div', 'permissions-panel') const fields = [] - L.DomUtil.createTitle(container, L._('Update permissions'), 'key') + L.DomUtil.createTitle(container, L._('Update permissions'), 'icon-key') if (this.isAnonymousMap()) { if (this.options.anonymous_edit_url) { const helpText = `${L._('Secret edit link:')}
${this.options.anonymous_edit_url diff --git a/umap/static/umap/js/umap.share.js b/umap/static/umap/js/umap.share.js index a4c0a65c..54befdb8 100644 --- a/umap/static/umap/js/umap.share.js +++ b/umap/static/umap/js/umap.share.js @@ -45,7 +45,11 @@ U.Share = L.Class.extend({ build: function () { this.container = L.DomUtil.create('div', '') - this.title = L.DomUtil.createTitle(this.container, L._('Share and download'), 'share') + this.title = L.DomUtil.createTitle( + this.container, + L._('Share and download'), + 'icon-share' + ) L.DomUtil.createCopiableInput( this.container,