From 53c151466eeabb04037450b8824568f8c64557cd Mon Sep 17 00:00:00 2001 From: cyclingbyte Date: Sat, 7 Sep 2024 15:06:07 +0200 Subject: [PATCH] feat: set panel width via options (#25) --- dev/main.js | 3 ++- src/leaflet-sidepanel.scss | 13 +++++++++---- src/leaflet-sidepanel.ts | 28 ++++++++++++++++++++++------ src/types/leaflet-sidepanel.ts | 1 + tests/leaflet.sidepanel.test.ts | 15 ++++++++------- 5 files changed, 42 insertions(+), 18 deletions(-) diff --git a/dev/main.js b/dev/main.js index 8bb090f..ddc50d8 100644 --- a/dev/main.js +++ b/dev/main.js @@ -12,11 +12,12 @@ const sidepanelLeft = L.control.sidepanel('mySidepanelLeft', { sidepanelLeft.addTo(map); const sidepanelRight = L.control.sidepanel('mySidepanelRight', { + hasTabs: false, panelPosition: 'right', tabsPosition: 'top', pushControls: true, darkMode: true, - defaultTab: 2, + size: '300px', }); sidepanelRight.addTo(map); diff --git a/src/leaflet-sidepanel.scss b/src/leaflet-sidepanel.scss index 87dee54..cf727d7 100644 --- a/src/leaflet-sidepanel.scss +++ b/src/leaflet-sidepanel.scss @@ -22,7 +22,6 @@ $green: #199900; $green-active: #116600; // panel -$panel-width: 400px; $panel-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; $panel-background-color: $white; @@ -130,9 +129,15 @@ $dark-toggle-button-background: url('#{$dark-toggle-button-arrow}') no-repeat 50% 50%; $toggle-button-arrow-opacity: 1; +:root { + --panel-width: 400px; // default panel width + --panel-width-left: 400px; // default panel width + --panel-width-right: 400px; // default panel width +} + // Panel .sidepanel { - width: $panel-width; + width: var(--panel-width); height: 100%; font-family: $panel-font-family; border: 0; @@ -647,7 +652,7 @@ $toggle-button-arrow-opacity: 1; // Animate control .leaflet-animate-control-container { &.left-opened .leaflet-left { - left: $panel-width; + left: var(--panel-width-left); transition: left 0.5s ease; @media screen and (max-width: 450px) { @@ -661,7 +666,7 @@ $toggle-button-arrow-opacity: 1; } &.right-opened .leaflet-right { - right: $panel-width; + right: var(--panel-width-right); transition: right 0.5s ease, right 0.5s ease; diff --git a/src/leaflet-sidepanel.ts b/src/leaflet-sidepanel.ts index 90d07d5..982b55d 100644 --- a/src/leaflet-sidepanel.ts +++ b/src/leaflet-sidepanel.ts @@ -42,11 +42,15 @@ class SidePanel extends L.Control { darkMode: false, pushControls: false, defaultTab: 1, + size: '400px', onTabClick: () => {}, onToggle: () => {}, ...options, // Merge with default options }; this._panel = L.DomUtil.get(id)!; // The `!` tells TypeScript we're sure the element exists + this._panel.style.setProperty('--panel-width', this.options.size!); // `!` 'cause we have a default value + + // Set the options L.setOptions(this, options); } @@ -62,6 +66,23 @@ class SidePanel extends L.Control { L.DomEvent.disableScrollPropagation(this._panel); L.DomEvent.disableClickPropagation(this._panel); + if (!!this.options.pushControls) { + const map = this._map; + const mapContainer = map instanceof L.Map ? map.getContainer() : map; + const controlsContainer = mapContainer.querySelector( + '.leaflet-control-container' + ) as HTMLElement; + + L.DomUtil.addClass( + controlsContainer, + 'leaflet-animate-control-container' + ); + controlsContainer.style.setProperty( + `--panel-width-${this.options.panelPosition}`, + this.options.size! + ); // `!` 'cause we have a default value + } + if (this.options.hasTabs) { this._initTabs(this.options.tabsPosition!); // `!` 'cause we have a default value } else { @@ -158,7 +179,7 @@ class SidePanel extends L.Control { if (this.options.pushControls) { const map = this._map; - if (map) { + if (!!map) { // TypeScript expects `map` to be an instance of `L.Map` but it can also be an HTMLElement // We assume that if it's not an instance of `L.Map`, it's an HTMLElement const mapContainer = map instanceof L.Map ? map.getContainer() : map; @@ -166,11 +187,6 @@ class SidePanel extends L.Control { '.leaflet-control-container' ) as HTMLElement; - L.DomUtil.addClass( - controlsContainer, - 'leaflet-animate-control-container' - ); - if (IS_OPENED) { L.DomUtil.removeClass( controlsContainer, diff --git a/src/types/leaflet-sidepanel.ts b/src/types/leaflet-sidepanel.ts index 4ee26bf..8376a64 100644 --- a/src/types/leaflet-sidepanel.ts +++ b/src/types/leaflet-sidepanel.ts @@ -11,6 +11,7 @@ declare module 'leaflet' { darkMode?: boolean; pushControls?: boolean; defaultTab?: number | string; + size?: string; onTabClick?: (tabLink: HTMLElement) => void; onToggle?: (opened: boolean) => void; } diff --git a/tests/leaflet.sidepanel.test.ts b/tests/leaflet.sidepanel.test.ts index 5df947c..d432963 100644 --- a/tests/leaflet.sidepanel.test.ts +++ b/tests/leaflet.sidepanel.test.ts @@ -157,12 +157,9 @@ describe('SidePanel', () => { ) as HTMLElement; expect( controlsContainer.classList.contains('leaflet-animate-control-container') - ).toBe(false); + ).toBe(true); sidePanel.toggle(); - expect( - controlsContainer.classList.contains('leaflet-animate-control-container') - ).toBe(true); expect( controlsContainer.classList.contains(options.panelPosition + '-opened') ).toBe(true); @@ -204,10 +201,16 @@ describe('SidePanel', () => { const controlsContainer = document.querySelector( '.leaflet-control-container' ) as HTMLElement; - sidePanel.toggle(); expect( controlsContainer.classList.contains('leaflet-animate-control-container') ).toBe(false); + expect( + controlsContainer.classList.toString().match(/-opened|-closed/g) + ).toBeNull(); + sidePanel.toggle(); + expect( + controlsContainer.classList.toString().match(/-opened|-closed/g) + ).toBeNull(); }); it('should warn if position option is set', () => { @@ -604,8 +607,6 @@ describe('SidePanel with HTMLElement', () => { // leaflet expects a map instance but also accepts HTMLElement .addTo(map); - sidePanel.toggle(); // This will trigger the `pushControls` logic - const controlsContainer = (map as unknown as HTMLElement).querySelector( '.leaflet-control-container' ) as HTMLElement;