diff --git a/Logic/Actors/SelectedFeatureHandler.ts b/Logic/Actors/SelectedFeatureHandler.ts index b45e87b931..7d431c7af5 100644 --- a/Logic/Actors/SelectedFeatureHandler.ts +++ b/Logic/Actors/SelectedFeatureHandler.ts @@ -10,7 +10,7 @@ import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"; * Makes sure the hash shows the selected element and vice-versa. */ export default class SelectedFeatureHandler { - private static readonly _no_trigger_on = new Set(["welcome", "copyright", "layers", "new", "", undefined]) + private static readonly _no_trigger_on = new Set(["welcome", "copyright", "layers", "new", "filter","", undefined]) private readonly hash: UIEventSource; private readonly state: { selectedElement: UIEventSource, @@ -70,7 +70,7 @@ export default class SelectedFeatureHandler { this.initialLoad() } - + /** * On startup: check if the hash is loaded and eventually zoom to it @@ -85,6 +85,11 @@ export default class SelectedFeatureHandler { return; } + if (!(hash.startsWith("node") || hash.startsWith("way") || hash.startsWith("relation"))) { + return; + } + + OsmObject.DownloadObjectAsync(hash).then(obj => { try { @@ -129,26 +134,25 @@ export default class SelectedFeatureHandler { // If a feature is selected via the hash, zoom there private zoomToSelectedFeature() { - + const selected = this.state.selectedElement.data - if(selected === undefined){ + if (selected === undefined) { return } - - const centerpoint= GeoOperations.centerpointCoordinates(selected) + + const centerpoint = GeoOperations.centerpointCoordinates(selected) const location = this.state.locationControl; location.data.lon = centerpoint[0] location.data.lat = centerpoint[1] - + const minZoom = Math.max(14, ...(this.state.layoutToUse?.layers?.map(l => l.minzoomVisible) ?? [])) - if(location.data.zoom < minZoom ){ + if (location.data.zoom < minZoom) { location.data.zoom = minZoom } - + location.ping(); - - - + + } } \ No newline at end of file diff --git a/Logic/State/FeatureSwitchState.ts b/Logic/State/FeatureSwitchState.ts index 2315280ca5..0f5df51f78 100644 --- a/Logic/State/FeatureSwitchState.ts +++ b/Logic/State/FeatureSwitchState.ts @@ -144,31 +144,20 @@ export default class FeatureSwitchState { } - this.featureSwitchIsTesting = QueryParameters.GetQueryParameter( + this.featureSwitchIsTesting = QueryParameters.GetBooleanQueryParameter( "test", ""+testingDefaultValue, "If true, 'dryrun' mode is activated. The app will behave as normal, except that changes to OSM will be printed onto the console instead of actually uploaded to osm.org" - ).map( - (str) => str === "true", - [], - (b) => "" + b - ); + ) - this.featureSwitchIsDebugging = QueryParameters.GetQueryParameter( + this.featureSwitchIsDebugging = QueryParameters.GetBooleanQueryParameter( "debug", "false", "If true, shows some extra debugging help such as all the available tags on every object" - ).map( - (str) => str === "true", - [], - (b) => "" + b - ); + ) - this.featureSwitchFakeUser = QueryParameters.GetQueryParameter("fake-user", "false", + this.featureSwitchFakeUser = QueryParameters.GetBooleanQueryParameter("fake-user", "false", "If true, 'dryrun' mode is activated and a fake user account is loaded") - .map(str => str === "true", [], b => "" + b); - - this.overpassUrl = QueryParameters.GetQueryParameter("overpassUrl", diff --git a/Logic/State/MapState.ts b/Logic/State/MapState.ts index afcbb1bf21..00a05dd61c 100644 --- a/Logic/State/MapState.ts +++ b/Logic/State/MapState.ts @@ -119,7 +119,7 @@ export default class MapState extends UserRelatedState { this.overlayToggles = this.layoutToUse.tileLayerSources.filter(c => c.name !== undefined).map(c => ({ config: c, - isDisplayed: QueryParameters.GetQueryParameter("overlay-" + c.id, "" + c.defaultState, "Wether or not the overlay " + c.id + " is shown").map(str => str === "true", [], b => "" + b) + isDisplayed: QueryParameters.GetBooleanQueryParameter("overlay-" + c.id, "" + c.defaultState, "Wether or not the overlay " + c.id + " is shown") })) this.filteredLayers = this.InitializeFilteredLayers() @@ -170,17 +170,12 @@ export default class MapState extends UserRelatedState { .map(value => value === "yes", [], enabled => { return enabled ? "yes" : ""; }) - isDisplayed.addCallbackAndRun(d => console.log("IsDisplayed for layer", layer.id, "is currently", d)) } else { - isDisplayed = QueryParameters.GetQueryParameter( + isDisplayed = QueryParameters.GetBooleanQueryParameter( "layer-" + layer.id, "true", "Wether or not layer " + layer.id + " is shown" - ).map( - (str) => str !== "false", - [], - (b) => b.toString() - ); + ) } const flayer = { isDisplayed: isDisplayed, diff --git a/Logic/Web/QueryParameters.ts b/Logic/Web/QueryParameters.ts index 36ecc76803..8af95a69bd 100644 --- a/Logic/Web/QueryParameters.ts +++ b/Logic/Web/QueryParameters.ts @@ -55,6 +55,10 @@ export class QueryParameters { return source; } + public static GetBooleanQueryParameter(key: string, deflt: string, documentation?: string): UIEventSource{ + return QueryParameters.GetQueryParameter(key, deflt, documentation).map(str => str === "true", [], b => ""+b) + } + public static GenerateQueryParameterDocs(): string { const docs = [QueryParameters.QueryParamDocsIntro]; for (const key in QueryParameters.documentation) { diff --git a/UI/Base/Ornament.ts b/UI/Base/Ornament.ts deleted file mode 100644 index 7c2798892f..0000000000 --- a/UI/Base/Ornament.ts +++ /dev/null @@ -1,11 +0,0 @@ -import {FixedUiElement} from "./FixedUiElement"; - -export default class Ornament extends FixedUiElement { - - constructor() { - super(""); - this.SetClass("pt-3 pb-3 flex justify-center box-border") - } - - -} \ No newline at end of file diff --git a/UI/Base/ScrollableFullScreen.ts b/UI/Base/ScrollableFullScreen.ts index da8114f8ca..07124f997c 100644 --- a/UI/Base/ScrollableFullScreen.ts +++ b/UI/Base/ScrollableFullScreen.ts @@ -1,11 +1,11 @@ import {UIElement} from "../UIElement"; import Svg from "../../Svg"; import Combine from "./Combine"; -import Ornament from "./Ornament"; import {FixedUiElement} from "./FixedUiElement"; import {UIEventSource} from "../../Logic/UIEventSource"; import Hash from "../../Logic/Web/Hash"; import BaseUIElement from "../BaseUIElement"; +import Img from "./Img"; /** * @@ -18,26 +18,22 @@ import BaseUIElement from "../BaseUIElement"; */ export default class ScrollableFullScreen extends UIElement { private static readonly empty = new FixedUiElement(""); - private static readonly _actor = ScrollableFullScreen.InitActor(); private static _currentlyOpen: ScrollableFullScreen; public isShown: UIEventSource; private _component: BaseUIElement; private _fullscreencomponent: BaseUIElement; - private _hashToSet: string; constructor(title: ((mode: string) => BaseUIElement), content: ((mode: string) => BaseUIElement), - hashToSet: string, isShown: UIEventSource = new UIEventSource(false) ) { super(); this.isShown = isShown; - this._hashToSet = hashToSet; this._component = this.BuildComponent(title("desktop"), content("desktop"), isShown) .SetClass("hidden md:block"); - this._fullscreencomponent = this.BuildComponent(title("mobile"), content("mobile"), isShown); + this._fullscreencomponent = this.BuildComponent(title("mobile"), content("mobile").SetClass("pb-20"), isShown); + - const self = this; isShown.addCallback(isShown => { if (isShown) { @@ -56,15 +52,6 @@ export default class ScrollableFullScreen extends UIElement { Hash.hash.setData(undefined); } - private static InitActor() { - Hash.hash.addCallback(hash => { - if (hash === undefined || hash === "") { - ScrollableFullScreen.clear() - } - }); - return true; - } - InnerRender(): BaseUIElement { return this._component; } @@ -72,9 +59,6 @@ export default class ScrollableFullScreen extends UIElement { Activate(): void { this.isShown.setData(true) this._fullscreencomponent.AttachTo("fullscreen"); - if (this._hashToSet != undefined) { - Hash.hash.setData(this._hashToSet) - } const fs = document.getElementById("fullscreen"); ScrollableFullScreen._currentlyOpen = this; fs.classList.remove("hidden") @@ -83,25 +67,26 @@ export default class ScrollableFullScreen extends UIElement { private BuildComponent(title: BaseUIElement, content: BaseUIElement, isShown: UIEventSource) { const returnToTheMap = new Combine([ - Svg.back_svg().SetClass("block md:hidden"), - Svg.close_svg().SetClass("hidden md:block") - ]) - .onClick(() => { - isShown.setData(false) - }).SetClass("mb-2 bg-blue-50 rounded-full w-12 h-12 p-1.5 flex-shrink-0") + new Img(Svg.back.replace(/#000000/g,"#cccccc"),true) + .SetClass("block md:hidden w-12 h-12 p-2"), + new Img(Svg.close.replace(/#000000/g,"#cccccc"),true) + .SetClass("hidden md:block w-12 h-12 p-3") + ]).SetClass("rounded-full p-0 flex-shrink-0 self-center") - title.SetClass("block text-l sm:text-xl md:text-2xl w-full font-bold p-2 pl-4 max-h-20vh overflow-y-auto") - const ornament = new Combine([new Ornament().SetStyle("height:5em;")]) - .SetClass("md:hidden h-5") + returnToTheMap.onClick(() => { + isShown.setData(false) + }) + + title.SetClass("block text-l sm:text-xl md:text-2xl w-full font-bold p-0 max-h-20vh overflow-y-auto") return new Combine([ new Combine([ new Combine([returnToTheMap, title]) - .SetClass("border-b-2 border-black shadow md:shadow-none bg-white p-2 pb-0 md:p-0 flex flex-shrink-0"), - new Combine([content, ornament]) + .SetClass("border-b-1 border-black shadow bg-white flex flex-shrink-0 pt-1 pb-1 md:pt-0 md:pb-0"), + new Combine([content]) .SetClass("block p-2 md:pt-4 w-full h-full overflow-y-auto md:max-h-65vh"), // We add an ornament which takes around 5em. This is in order to make sure the Web UI doesn't hide ]).SetClass("flex flex-col h-full relative bg-white") - ]).SetClass("fixed top-0 left-0 right-0 h-screen w-screen md:max-h-65vh md:w-auto md:relative z-above-controls"); + ]).SetClass("fixed top-0 left-0 right-0 h-screen w-screen md:max-h-65vh md:w-auto md:relative z-above-controls md:rounded-xl overflow-hidden"); } diff --git a/UI/BigComponents/AllDownloads.ts b/UI/BigComponents/AllDownloads.ts index 3df26f53de..b49e77bcb0 100644 --- a/UI/BigComponents/AllDownloads.ts +++ b/UI/BigComponents/AllDownloads.ts @@ -9,12 +9,11 @@ import {DownloadPanel} from "./DownloadPanel"; import {SubtleButton} from "../Base/SubtleButton"; import Svg from "../../Svg"; import ExportPDF from "../ExportPDF"; -import {FixedUiElement} from "../Base/FixedUiElement"; export default class AllDownloads extends ScrollableFullScreen { constructor(isShown: UIEventSource) { - super(AllDownloads.GenTitle, AllDownloads.GeneratePanel, "layers", isShown); + super(AllDownloads.GenTitle, AllDownloads.GeneratePanel, isShown); } private static GenTitle(): BaseUIElement { diff --git a/UI/BigComponents/FullWelcomePaneWithTabs.ts b/UI/BigComponents/FullWelcomePaneWithTabs.ts index 8dc7cf668f..1862110ce2 100644 --- a/UI/BigComponents/FullWelcomePaneWithTabs.ts +++ b/UI/BigComponents/FullWelcomePaneWithTabs.ts @@ -30,7 +30,7 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { super( () => layoutToUse.title.Clone(), () => FullWelcomePaneWithTabs.GenerateContents(state, currentTab, isShown), - undefined, isShown + isShown ) } diff --git a/UI/BigComponents/LeftControls.ts b/UI/BigComponents/LeftControls.ts index b92adb54ab..4b2328533e 100644 --- a/UI/BigComponents/LeftControls.ts +++ b/UI/BigComponents/LeftControls.ts @@ -26,12 +26,12 @@ export default class LeftControls extends Combine { featureSwitchEnableExport: UIEventSource, featureSwitchExportAsPdf: UIEventSource, filteredLayers: UIEventSource, - featureSwitchFilter: UIEventSource, - selectedElement: UIEventSource + featureSwitchFilter: UIEventSource }, guiState: { downloadControlIsOpened: UIEventSource, filterViewIsOpened: UIEventSource, + copyrightViewIsOpened: UIEventSource }) { const toggledCopyright = new ScrollableFullScreen( @@ -41,7 +41,7 @@ export default class LeftControls extends Combine { state.layoutToUse, new ContributorCount(state).Contributors ), - undefined + guiState.copyrightViewIsOpened ); const copyrightButton = new Toggle( @@ -49,8 +49,7 @@ export default class LeftControls extends Combine { new MapControlButton(Svg.copyright_svg()) .onClick(() => toggledCopyright.isShown.setData(true)), toggledCopyright.isShown - ) - .SetClass("p-0.5"); + ).SetClass("p-0.5"); const toggledDownload = new Toggle( new AllDownloads( @@ -73,11 +72,10 @@ export default class LeftControls extends Combine { () => Translations.t.general.layerSelection.title.Clone(), () => new FilterView(state.filteredLayers, state.overlayToggles).SetClass( - "block p-1 rounded-full" + "block p-1" ), - undefined, guiState.filterViewIsOpened - ), + ).SetClass("rounded-lg"), new MapControlButton(Svg.filter_svg()) .onClick(() => guiState.filterViewIsOpened.setData(true)), guiState.filterViewIsOpened @@ -90,18 +88,6 @@ export default class LeftControls extends Combine { ); - state.locationControl.addCallback(() => { - // Close the layer selection when the map is moved - toggledDownload.isEnabled.setData(false); - copyrightButton.isEnabled.setData(false); - toggledFilter.isEnabled.setData(false); - }); - - state.selectedElement.addCallbackAndRunD((_) => { - toggledDownload.isEnabled.setData(false); - copyrightButton.isEnabled.setData(false); - toggledFilter.isEnabled.setData(false); - }); super([filterButton, downloadButtonn, copyrightButton]) diff --git a/UI/DefaultGUI.ts b/UI/DefaultGUI.ts index fc195f90d7..9af6162335 100644 --- a/UI/DefaultGUI.ts +++ b/UI/DefaultGUI.ts @@ -26,44 +26,71 @@ import StrayClickHandler from "../Logic/Actors/StrayClickHandler"; import Lazy from "./Base/Lazy"; export class DefaultGuiState { - public readonly welcomeMessageIsOpened; + public readonly welcomeMessageIsOpened : UIEventSource; public readonly downloadControlIsOpened: UIEventSource; public readonly filterViewIsOpened: UIEventSource; - public readonly welcomeMessageOpenedTab + public readonly copyrightViewIsOpened: UIEventSource; + public readonly welcomeMessageOpenedTab: UIEventSource + public readonly allFullScreenStates: UIEventSource[] = [] constructor() { - this.filterViewIsOpened = QueryParameters.GetQueryParameter( - "filter-toggle", - "false", - "Whether or not the filter view is shown" - ).map( - (str) => str !== "false", - [], - (b) => "" + b - ); - this.welcomeMessageIsOpened = new UIEventSource(Hash.hash.data === undefined || - Hash.hash.data === "" || - Hash.hash.data == "welcome"); - this.welcomeMessageOpenedTab = QueryParameters.GetQueryParameter( + + + this.welcomeMessageOpenedTab = UIEventSource.asFloat(QueryParameters.GetQueryParameter( "tab", "0", `The tab that is shown in the welcome-message. 0 = the explanation of the theme,1 = OSM-credits, 2 = sharescreen, 3 = more themes, 4 = about mapcomplete (user must be logged in and have >${Constants.userJourney.mapCompleteHelpUnlock} changesets)` - ).map( - (str) => (isNaN(Number(str)) ? 0 : Number(str)), - [], - (n) => "" + n - ); - this.downloadControlIsOpened = - QueryParameters.GetQueryParameter( + )); + this.welcomeMessageIsOpened = QueryParameters.GetBooleanQueryParameter( + "welcome-control-toggle", + "false", + "Whether or not the welcome panel is shown" + ) + this.downloadControlIsOpened = QueryParameters.GetBooleanQueryParameter( "download-control-toggle", "false", "Whether or not the download panel is shown" - ).map( - (str) => str !== "false", - [], - (b) => "" + b - ); + ) + this.filterViewIsOpened = QueryParameters.GetBooleanQueryParameter( + "filter-toggle", + "false", + "Whether or not the filter view is shown" + ) + this.copyrightViewIsOpened = QueryParameters.GetBooleanQueryParameter( + "copyright-toggle", + "false", + "Whether or not the copyright view is shown" + ) + if(Hash.hash.data === "download"){ + this.downloadControlIsOpened.setData(true) + } + if(Hash.hash.data === "filter"){ + this.filterViewIsOpened.setData(true) + } + if(Hash.hash.data === "copyright"){ + this.copyrightViewIsOpened.setData(true) + } + if(Hash.hash.data === "" || Hash.hash.data === undefined || Hash.hash.data === "welcome"){ + this.welcomeMessageIsOpened.setData(true) + } + + this.allFullScreenStates.push(this.downloadControlIsOpened, this.filterViewIsOpened, this.copyrightViewIsOpened, this.welcomeMessageIsOpened) + + for (let i = 0; i < this.allFullScreenStates.length; i++){ + const fullScreenState = this.allFullScreenStates[i]; + for (let j = 0; j < this.allFullScreenStates.length; j++){ + if(i == j){ + continue + } + const otherState = this.allFullScreenStates[j]; + fullScreenState.addCallbackAndRunD(isOpened => { + if(isOpened){ + otherState.setData(false) + } + }) + } + } } } @@ -154,6 +181,7 @@ export default class DefaultGUI { Toggle.If(state.featureSwitchIframePopoutEnabled, iframePopout), state.featureSwitchWelcomeMessage ).AttachTo("messagesbox"); + new LeftControls(state, guiState).AttachTo("bottom-left"); new RightControls(state).AttachTo("bottom-right"); @@ -162,6 +190,21 @@ export default class DefaultGUI { document .getElementById("centermessage") .classList.add("pointer-events-none"); + + // We have to ping the welcomeMessageIsOpened and other isOpened-stuff to activate the FullScreenMessage if needed + for (const state of guiState.allFullScreenStates) { + if(state.data){ + state.ping() + } + } + + /** + * At last, if the map moves or an element is selected, we close all the panels just as well + */ + + state.selectedElement.addCallbackAndRunD((_) => { + guiState.allFullScreenStates.forEach(s => s.setData(false)) + }); } private InitWelcomeMessage() : BaseUIElement{ @@ -211,7 +254,6 @@ export default class DefaultGUI { const addNewPoint = new ScrollableFullScreen( () => Translations.t.general.add.title.Clone(), () => new SimpleAddUI(newPointDialogIsShown, filterViewIsOpened, state), - "new", newPointDialogIsShown ); addNewPoint.isShown.addCallback((isShown) => { diff --git a/UI/Popup/FeatureInfoBox.ts b/UI/Popup/FeatureInfoBox.ts index 155df8bdc0..86f3aa68fa 100644 --- a/UI/Popup/FeatureInfoBox.ts +++ b/UI/Popup/FeatureInfoBox.ts @@ -26,8 +26,7 @@ export default class FeatureInfoBox extends ScrollableFullScreen { layerConfig: LayerConfig, ) { super(() => FeatureInfoBox.GenerateTitleBar(tags, layerConfig), - () => FeatureInfoBox.GenerateContent(tags, layerConfig), - undefined); + () => FeatureInfoBox.GenerateContent(tags, layerConfig)); if (layerConfig === undefined) { throw "Undefined layerconfig"; diff --git a/assets/svg/close.svg b/assets/svg/close.svg index 1d43446560..ded2ef0e4e 100644 --- a/assets/svg/close.svg +++ b/assets/svg/close.svg @@ -2,83 +2,80 @@ - - - - - - - - - image/svg+xml - - - - - - - - - - - + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="100" + height="100" + viewBox="0 0 26.458333 26.458334" + version="1.1" + id="svg8" + sodipodi:docname="close.svg" + inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"> + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/css/index-tailwind-output.css b/css/index-tailwind-output.css index 63c10a8d0c..ee61e9cea2 100644 --- a/css/index-tailwind-output.css +++ b/css/index-tailwind-output.css @@ -856,10 +856,6 @@ video { margin-left: 0.75rem; } -.mb-2 { - margin-bottom: 0.5rem; -} - .mr-4 { margin-right: 1rem; } @@ -924,6 +920,14 @@ video { margin-right: 0.75rem; } +.mb-2 { + margin-bottom: 0.5rem; +} + +.mb-0 { + margin-bottom: 0px; +} + .box-border { box-sizing: border-box; } @@ -988,10 +992,6 @@ video { height: 3rem; } -.h-5 { - height: 1.25rem; -} - .h-screen { height: 100vh; } @@ -1279,10 +1279,6 @@ video { border-width: 2px; } -.border-b-2 { - border-bottom-width: 2px; -} - .border-b { border-bottom-width: 1px; } @@ -1316,11 +1312,6 @@ video { background-color: rgba(255, 255, 255, var(--tw-bg-opacity)); } -.bg-blue-50 { - --tw-bg-opacity: 1; - background-color: rgba(239, 246, 255, var(--tw-bg-opacity)); -} - .bg-blue-100 { --tw-bg-opacity: 1; background-color: rgba(219, 234, 254, var(--tw-bg-opacity)); @@ -1386,32 +1377,28 @@ video { padding: 0.5rem; } -.p-0\.5 { - padding: 0.125rem; -} - .p-0 { padding: 0px; } +.p-0\.5 { + padding: 0.125rem; +} + .pl-2 { padding-left: 0.5rem; } -.pt-3 { - padding-top: 0.75rem; +.pb-20 { + padding-bottom: 5rem; } -.pb-3 { - padding-bottom: 0.75rem; +.pt-1 { + padding-top: 0.25rem; } -.pl-4 { - padding-left: 1rem; -} - -.pb-0 { - padding-bottom: 0px; +.pb-1 { + padding-bottom: 0.25rem; } .pl-1 { @@ -1426,6 +1413,10 @@ video { padding-top: 1.5rem; } +.pb-3 { + padding-bottom: 0.75rem; +} + .pl-5 { padding-left: 1.25rem; } @@ -1434,6 +1425,10 @@ video { padding-right: 0.75rem; } +.pl-4 { + padding-left: 1rem; +} + .pr-4 { padding-right: 1rem; } @@ -2187,6 +2182,7 @@ li::marker { .leaflet-popup-content { width: 45em !important; + margin: 0.25rem !important; } .leaflet-div-icon { @@ -2422,8 +2418,8 @@ li::marker { flex-direction: row; } - .md\:p-0 { - padding: 0px; + .md\:rounded-xl { + border-radius: 0.75rem; } .md\:p-1 { @@ -2442,6 +2438,14 @@ li::marker { padding: 0.75rem; } + .md\:pt-0 { + padding-top: 0px; + } + + .md\:pb-0 { + padding-bottom: 0px; + } + .md\:pt-4 { padding-top: 1rem; } @@ -2461,11 +2465,6 @@ li::marker { line-height: 1.75rem; } - .md\:shadow-none { - --tw-shadow: 0 0 #0000; - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); - } - .md\:w-160 { width: 40rem; } diff --git a/index.css b/index.css index 6eb113abcf..108f02fe27 100644 --- a/index.css +++ b/index.css @@ -424,6 +424,7 @@ li::marker { .leaflet-popup-content { width: 45em !important; + margin: 0.25rem !important; } .leaflet-div-icon {