diff --git a/umap/static/umap/base.css b/umap/static/umap/base.css index ded44fc6..a015e3a2 100644 --- a/umap/static/umap/base.css +++ b/umap/static/umap/base.css @@ -266,6 +266,11 @@ button.flat, min-height: inherit; width: initial; display: initial; + line-height: inherit; +} +button.flat:hover, +[type="button"].flat:hover, +.dark [type="button"].flat:hover { text-decoration: underline; } .help-text, .helptext { diff --git a/umap/static/umap/css/panel.css b/umap/static/umap/css/panel.css index 9591615e..f4ea420d 100644 --- a/umap/static/umap/css/panel.css +++ b/umap/static/umap/css/panel.css @@ -25,7 +25,7 @@ } .panel.full.on { visibility: visible; - right: var(--panel-gutter); + right: calc(var(--panel-gutter) * 2 + var(--control-size)); left: var(--panel-gutter); height: initial; max-height: initial; @@ -41,41 +41,6 @@ height: calc(100% - var(--panel-header-height)); /* Minus size of toolbox */ padding: var(--panel-gutter); } -.panel .toolbox { - padding: 5px 10px; - overflow: hidden; - display: flex; - flex-direction: row-reverse; - font-size: 10px; - justify-content: flex-start; - gap: 5px; - line-height: 2.2em; - background-color: #fff; - position: sticky; - top: 0; - height: var(--panel-header-height); -} -.panel.dark .toolbox { - background-color: var(--color-darkGray); -} -.panel .toolbox li { - cursor: pointer; - display: inline; - padding: 0 2px; - border: 1px solid #b6b6b3; - border-radius: 2px; -} -.panel.dark .toolbox -.panel.dark .toolbox li { - color: #d3dfeb; - border: 1px solid #202425; -} -.panel .toolbox li:hover { - background-color: #d4d4d2; -} -.panel.dark .toolbox li:hover { - background-color: #353c3e; -} .panel h3 { line-height: 120%; } diff --git a/umap/static/umap/css/window.css b/umap/static/umap/css/window.css new file mode 100644 index 00000000..11195daa --- /dev/null +++ b/umap/static/umap/css/window.css @@ -0,0 +1,36 @@ +.window .buttons { + padding: 5px 10px; + overflow: hidden; + display: flex; + flex-direction: row-reverse; + font-size: 10px; + justify-content: flex-start; + gap: 5px; + line-height: 2.2em; + background-color: inherit; + position: sticky; + top: 0; + height: var(--panel-header-height); +} +.window .buttons li { + cursor: pointer; + display: inline; + padding: 0 2px; + border: 1px solid #b6b6b3; + border-radius: 2px; +} +.window.dark .buttons +.window.dark .buttons li { + color: #d3dfeb; + border: 1px solid #202425; +} +.window.dark[data-level="error"] .buttons li:hover, +.window.dark[data-level="error"] .buttons li button:hover { + background-color: darkred; +} +.window .buttons li:hover { + background-color: #d4d4d2; +} +.window.dark .buttons li:hover { + background-color: #353c3e; +} diff --git a/umap/static/umap/js/components/alerts/alert.css b/umap/static/umap/js/components/alerts/alert.css index 85df668c..d05da690 100644 --- a/umap/static/umap/js/components/alerts/alert.css +++ b/umap/static/umap/js/components/alerts/alert.css @@ -5,7 +5,7 @@ padding: var(--panel-gutter); position: absolute; box-shadow: 0 1px 7px #999999; - background: none repeat scroll 0 0 rgba(20, 22, 23, 0.8); + background: none repeat scroll 0 0 var(--color-darkGray); font-weight: bold; color: #fff; font-size: 0.8em; @@ -25,18 +25,6 @@ [role="dialog"] > div { margin: 0 auto; } -[role="dialog"] [data-close].umap-close-link { - color: #fff; - max-width: 42px; - line-height: initial; - margin: 0; - margin-left: var(--panel-gutter); - background-color: #202425; - font-size: 0.7rem; -} -[role="dialog"] [data-close].umap-close-link .icon + span { - margin-left: 0; -} #link-wrapper form { display: flex; } diff --git a/umap/static/umap/js/components/alerts/alert.html b/umap/static/umap/js/components/alerts/alert.html index 553abb03..7aeb16c7 100644 --- a/umap/static/umap/js/components/alerts/alert.html +++ b/umap/static/umap/js/components/alerts/alert.html @@ -5,20 +5,22 @@ diff --git a/umap/static/umap/js/components/alerts/alert.js b/umap/static/umap/js/components/alerts/alert.js index 3646944b..8be4895c 100644 --- a/umap/static/umap/js/components/alerts/alert.js +++ b/umap/static/umap/js/components/alerts/alert.js @@ -1,3 +1,4 @@ +import { translate } from '../../modules/i18n.js' import { uMapElement } from '../base.js' class uMapAlert extends uMapElement { @@ -96,7 +97,7 @@ class uMapAlertCreation extends uMapAlert { button.addEventListener('click', (event) => { event.preventDefault() L.Util.copyToClipboard(editLink) - event.target.value = L._('✅ Copied!') + event.target.value = translate('✅ Copied!') }) if (sendLink) { this.formWrapper.removeAttribute('hidden') diff --git a/umap/static/umap/js/components/base.js b/umap/static/umap/js/components/base.js index f4247a22..0d2aaefc 100644 --- a/umap/static/umap/js/components/base.js +++ b/umap/static/umap/js/components/base.js @@ -1,8 +1,8 @@ -export class uMapElement extends HTMLElement { - static EVENT_PREFIX = 'umap' +const EVENT_PREFIX = 'umap' +export class uMapElement extends HTMLElement { static emit(type, detail = {}) { - const event = new CustomEvent(`${uMapElement.EVENT_PREFIX}:${type}`, { + const event = new CustomEvent(`${EVENT_PREFIX}:${type}`, { bubbles: true, cancelable: true, detail: detail, @@ -36,14 +36,14 @@ export class uMapElement extends HTMLElement { handleEvent(event) { event.preventDefault() // From `umap:alert` to `alert`. - const eventName = event.type.replace(`${uMapElement.EVENT_PREFIX}:`, '') + const eventName = event.type.replace(`${EVENT_PREFIX}:`, '') // From `alert` event type to `onAlert` call against that class. this[`on${eventName.charAt(0).toUpperCase() + eventName.slice(1)}`](event) } listen(eventName) { // Using `this` as a listener will call `handleEvent` under the hood. - document.addEventListener(`${uMapElement.EVENT_PREFIX}:${eventName}`, this) + document.addEventListener(`${EVENT_PREFIX}:${eventName}`, this) } } diff --git a/umap/static/umap/js/modules/ui/dialog.js b/umap/static/umap/js/modules/ui/dialog.js index 6833fd13..24aa825a 100644 --- a/umap/static/umap/js/modules/ui/dialog.js +++ b/umap/static/umap/js/modules/ui/dialog.js @@ -4,7 +4,7 @@ import { translate } from '../i18n.js' export default class Dialog { constructor(parent) { this.parent = parent - this.container = DomUtil.create('dialog', 'umap-dialog', this.parent) + this.container = DomUtil.create('dialog', 'umap-dialog window', this.parent) DomEvent.disableClickPropagation(this.container) DomEvent.on(this.container, 'contextmenu', DomEvent.stopPropagation) // Do not activate our custom context menu. DomEvent.on(this.container, 'wheel', DomEvent.stopPropagation) @@ -26,15 +26,14 @@ export default class Dialog { if (className) { this.container.classList.add(className) } - const closeButton = DomUtil.createButton( - 'umap-close-link', - this.container, - '', - () => this.container.close() + const buttonsContainer = DomUtil.create('ul', 'buttons', this.container) + const closeButton = DomUtil.createButtonIcon( + DomUtil.create('li', '', buttonsContainer), + 'icon-close', + translate('Close') ) - DomUtil.createIcon(closeButton, 'icon-close') - const label = DomUtil.create('span', '', closeButton) - label.title = label.textContent = translate('Close') + DomEvent.on(closeButton, 'click', this.close, this) + this.container.appendChild(buttonsContainer) this.container.appendChild(content) } } diff --git a/umap/static/umap/js/modules/ui/panel.js b/umap/static/umap/js/modules/ui/panel.js index 0aa04b05..e236e82a 100644 --- a/umap/static/umap/js/modules/ui/panel.js +++ b/umap/static/umap/js/modules/ui/panel.js @@ -25,27 +25,34 @@ export class Panel { } open({ content, className, actions = [] } = {}) { - this.container.className = `with-transition panel ${this.classname} ${this.mode || ''}` + this.container.className = `with-transition panel window ${this.classname} ${ + this.mode || '' + }` this.container.innerHTML = '' - const actionsContainer = DomUtil.create('ul', 'toolbox', this.container) + const actionsContainer = DomUtil.create('ul', 'buttons', this.container) const body = DomUtil.create('div', 'body', this.container) body.appendChild(content) - const closeLink = DomUtil.create('li', 'umap-close-link', actionsContainer) - DomUtil.add('i', 'icon icon-16 icon-close', closeLink) - closeLink.title = translate('Close') - const resizeLink = DomUtil.create('li', 'umap-resize-link', actionsContainer) - DomUtil.add('i', 'icon icon-16 icon-resize', resizeLink) - resizeLink.title = translate('Toggle size') - for (let action of actions) { - actionsContainer.appendChild(action) + const closeButton = DomUtil.createButtonIcon( + DomUtil.create('li', '', actionsContainer), + 'icon-close', + translate('Close') + ) + const resizeButton = DomUtil.createButtonIcon( + DomUtil.create('li', '', actionsContainer), + 'icon-resize', + translate('Toggle size') + ) + for (const action of actions) { + const element = DomUtil.element({ tagName: 'li', parent: actionsContainer }) + element.appendChild(action) } if (className) DomUtil.addClass(body, className) const promise = new Promise((resolve, reject) => { DomUtil.addClass(this.container, 'on') resolve() }) - DomEvent.on(closeLink, 'click', this.close, this) - DomEvent.on(resizeLink, 'click', this.resize, this) + DomEvent.on(closeButton, 'click', this.close, this) + DomEvent.on(resizeButton, 'click', this.resize, this) return promise } diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 432ba30a..741a57c5 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -1466,17 +1466,19 @@ U.DataLayer = L.Evented.extend({ '_blank' ) } - const button = L.DomUtil.create('li', '') - L.DomUtil.create('i', 'icon icon-16 icon-back', button) - button.title = L._('Back to layers') + const backButton = L.DomUtil.createButtonIcon( + undefined, + 'icon-back', + L._('Back to layers') + ) // Fixme: remove me when this is merged and released // https://github.com/Leaflet/Leaflet/pull/9052 - L.DomEvent.disableClickPropagation(button) - L.DomEvent.on(button, 'click', this.map.editDatalayers, this.map) + L.DomEvent.disableClickPropagation(backButton) + L.DomEvent.on(backButton, 'click', this.map.editDatalayers, this.map) this.map.editPanel.open({ content: container, - actions: [button], + actions: [backButton], }) }, diff --git a/umap/static/umap/js/umap.tableeditor.js b/umap/static/umap/js/umap.tableeditor.js index 389ae61b..5cbaa034 100644 --- a/umap/static/umap/js/umap.tableeditor.js +++ b/umap/static/umap/js/umap.tableeditor.js @@ -95,10 +95,13 @@ U.TableEditor = L.Class.extend({ this.renderHeaders() this.body.innerHTML = '' this.datalayer.eachLayer(this.renderRow, this) - const addButton = L.DomUtil.create('li', 'add-property') - L.DomUtil.createIcon(addButton, 'icon-add') - const label = L.DomUtil.create('span', '', addButton) - label.textContent = label.title = L._('Add a new property') + const addButton = L.DomUtil.createButton( + 'flat', + undefined, + L._('Add a new property') + ) + const iconElement = L.DomUtil.createIcon(addButton, 'icon-add') + addButton.insertBefore(iconElement, addButton.firstChild) const addProperty = function () { const newName = prompt(L._('Please enter the name of the property')) if (!newName || !this.validateName(newName)) return diff --git a/umap/static/umap/map.css b/umap/static/umap/map.css index e17d8d92..d36c2cf9 100644 --- a/umap/static/umap/map.css +++ b/umap/static/umap/map.css @@ -659,14 +659,14 @@ ul.photon-autocomplete { } .umap-caption-bar-enabled .umap-caption-bar { display: block; - height: var(--header-height); + height: var(--footer-height); background-color: #fff; width: 100%; position: absolute; left: 0; bottom: 0; right: 0; - padding: 0 0 0 5px; + padding: var(--gutter); text-align: left; line-height: 100%; cursor: auto; diff --git a/umap/static/umap/vars.css b/umap/static/umap/vars.css index 8d76d200..eb3fe177 100644 --- a/umap/static/umap/vars.css +++ b/umap/static/umap/vars.css @@ -20,13 +20,14 @@ --button-neutral-color: var(--color-darkGray); /* Sizes and spaces */ + --gutter: 8px; --panel-gutter: 10px; --panel-bottom: 40px; --panel-header-height: 36px; --panel-width: 400px; --header-height: 46px; --current-header-height: 0px; - --footer-height: 46px; + --footer-height: 28px; --current-footer-height: 0px; --control-size: 36px; } diff --git a/umap/templates/umap/css.html b/umap/templates/umap/css.html index e199ad6d..06ce487e 100644 --- a/umap/templates/umap/css.html +++ b/umap/templates/umap/css.html @@ -29,6 +29,7 @@ + diff --git a/umap/tests/integration/test_picto.py b/umap/tests/integration/test_picto.py index b8541f8b..d4b38954 100644 --- a/umap/tests/integration/test_picto.py +++ b/umap/tests/integration/test_picto.py @@ -171,7 +171,7 @@ def test_can_use_remote_url_as_picto(openmap, live_server, page, pictos): input_el.blur() expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg") # Now close and reopen the form, it should still be the URL tab - close = page.locator(".panel.right.on .toolbox").get_by_title("Close") + close = page.locator(".panel.right.on .buttons").get_by_title("Close") expect(close).to_be_visible() close.click() edit_settings.click() @@ -210,7 +210,7 @@ def test_can_use_char_as_picto(openmap, live_server, page, pictos): expect(marker).to_have_count(1) expect(marker).to_have_text("♩") # Now close and reopen the form, it should still be the URL tab - close = page.locator(".panel.right.on .toolbox").get_by_title("Close") + close = page.locator(".panel.right.on .buttons").get_by_title("Close") expect(close).to_be_visible() close.click() edit_settings.click()