@panoramax/web-viewer 5.2.0-develop-6a40c2ee → 5.2.0-develop-434137e7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,12 @@
1
1
  import { LitElement, css, html, nothing } from "lit";
2
2
  import { fa, onceParentAvailable } from "../../utils/widgets.js";
3
- import { faSvg, select, titles } from "../styles.js";
3
+ import { faSvg, select, titles, panel } from "../styles.js";
4
4
  import { COLORS, GPS_VALUES } from "../../utils/utils.js";
5
- import { faEarthEurope, faInfoCircle, faPalette } from "@fortawesome/free-solid-svg-icons";
5
+ import { faEarthEurope, faInfoCircle, faPalette, faXmark } from "@fortawesome/free-solid-svg-icons";
6
6
  import { MAP_THEMES_STYLES } from "../../utils/map.js";
7
- import { DISABLED_LEVEL, initIndoorEqualOnMap } from "../../utils/indoor.js";
8
- import { BASEMAPS_DEFAULT_IDS } from "../../utils/MapStyleComposer.js";
9
7
  import { classMap } from "lit/directives/class-map.js";
8
+ import { DISABLED_LEVEL, initIndoorEqualOnMap } from "../../utils/indoor.js";
9
+
10
10
 
11
11
  /**
12
12
  * Map Layers menu allows user to select background and map theme.
@@ -20,16 +20,67 @@ import { classMap } from "lit/directives/class-map.js";
20
20
  */
21
21
  export default class MapLayers extends LitElement {
22
22
  /** @private */
23
- static styles = [ faSvg, titles, select, css`
23
+ static styles = [ panel, faSvg, titles, select, css`
24
+ :host {
25
+ display: flex;
26
+ flex-direction: column;
27
+ align-items: end;
28
+ gap: 5px;
29
+ max-width: calc(100vw - 20px);
30
+ }
31
+
32
+ .btn-close {
33
+ position: absolute;
34
+ top: 8px;
35
+ right: 5px;
36
+ z-index: 10;
37
+ }
38
+
39
+ .btn-close svg {
40
+ height: 16px;
41
+ }
42
+
43
+ .pnx-panel {
44
+ position: relative;
45
+ min-width: unset;
46
+ }
47
+
48
+ .map-layers {
49
+ max-width: 100%;
50
+ overflow-x: auto;
51
+ padding: 10px 0;
52
+ }
53
+
54
+ .map-layers-blocks { display: flex; }
55
+
56
+ .map-layers-block {
57
+ border-right: 2px solid var(--grey-pale);
58
+ padding: 0 15px;
59
+ }
60
+
61
+ .map-layers-block:last-child { border-right: none; }
62
+ .map-layers-block-bg { padding-left: 18px; }
63
+
64
+ .map-layers-block h4 {
65
+ margin: 0 0 10px 0;
66
+ }
67
+
68
+ pnx-switch {
69
+ padding: 0 15px 0 0;
70
+ box-sizing: border-box;
71
+ float: right;
72
+ }
73
+
24
74
  .legend {
25
75
  display: flex;
26
76
  flex-wrap: wrap;
27
- margin-top: 5px;
28
77
  justify-content: space-evenly;
78
+ padding: 5px 10px;
79
+ gap: 10px;
80
+ align-items: center;
29
81
  }
30
82
 
31
83
  .legend-entry {
32
- margin: 10px 8px 5px 0px;
33
84
  line-height: 12px;
34
85
  display: flex;
35
86
  align-items: center;
@@ -52,6 +103,37 @@ export default class MapLayers extends LitElement {
52
103
  justify-content: center;
53
104
  gap: 0;
54
105
  }
106
+
107
+ @media screen and (max-width: 576px) {
108
+ :host {
109
+ max-width: 100%;
110
+ align-items: center;
111
+ }
112
+ .map-layers {
113
+ border: none;
114
+ width: 100%;
115
+ padding: 0 20px;
116
+ }
117
+ .map-layers-blocks {
118
+ flex-direction: column-reverse;
119
+ gap: 20px;
120
+ text-align: center;
121
+ }
122
+ .map-layers-block {
123
+ padding: 0;
124
+ border: none;
125
+ }
126
+ pnx-switch {
127
+ float: unset;
128
+ padding: 0;
129
+ }
130
+ .legend {
131
+ border: none;
132
+ margin: 10px 0;
133
+ min-height: 50px;
134
+ background: var(--grey-very-pale);
135
+ }
136
+ }
55
137
  ` ];
56
138
 
57
139
  /** @private */
@@ -82,94 +164,67 @@ export default class MapLayers extends LitElement {
82
164
  }
83
165
  }
84
166
 
85
- /** @private */
86
- _onThemeSelect(e) {
87
- this.theme = e.target.value;
88
- this._parent?.mapStyleComposer.setPanoramaxTheme(this.theme);
89
- }
90
-
91
- /** @private */
92
- _onBgChange(e) {
93
- this._parent?.mapStyleComposer.switchBasemap(e.target.value || "streets");
94
- }
95
167
 
96
168
  /** @private */
97
169
  render() {
98
- const parts = [];
99
- const hasIndoor = this._parent?.map?.indoorEqual || this._parent?.map?._options?.indoor?.visible === false;
100
170
  const isV2 = this._parent?.mapStyleComposer?._getPanoramaxStyleVersion() === 2;
101
-
102
- // Background selector
103
- if(this._parent?.mapStyleComposer?.hasManyBasemaps?.()) {
104
- parts.push(html`
105
- <h4>${fa(faEarthEurope)} ${this._parent?._t.pnx.map_background}</h4>
106
- `);
107
-
108
- if(this._parent.mapStyleComposer.hasStreetsAerialBasemaps()) {
109
- parts.push(html`
110
- <pnx-map-background ._parent=${this._parent} style="margin-bottom: 10px"></pnx-map-background>
111
- `);
112
- }
113
- if(this._parent.mapStyleComposer.hasComplementaryBasemaps()) {
114
- const defaultOpt = html`
115
- <option value="" .selected=${BASEMAPS_DEFAULT_IDS.includes(this._parent.mapStyleComposer.basemap)}>
116
- ${this._parent.mapStyleComposer.hasStreetsAerialBasemaps()
117
- ? this._parent?._t.pnx.map_background_more
118
- : this._parent?._t.pnx.map_background_default
119
- }
120
- </option>
121
- `;
122
- const layers = Object
123
- .entries(this._parent.mapStyleComposer.layerRanges.basemaps)
124
- .filter(([bid,]) => !BASEMAPS_DEFAULT_IDS.includes(bid))
125
- .map(([bid, b]) => html`
126
- <option value="${bid}" .selected=${this._parent.mapStyleComposer.basemap === bid}>
127
- ${b.layers[0]?.metadata?.name || bid}
128
- </option>
129
- `);
130
- parts.push(html`
131
- <select id="pnx-map-bg-more" style="width: 100%;" @change=${this._onBgChange}>
132
- ${defaultOpt}
133
- ${layers}
134
- </select>
135
- `);
136
- }
137
- }
138
-
139
- // Level selector for indoor=
171
+ const hasIndoor = this._parent?.map?.indoorEqual || this._parent?.map?._options?.indoor?.visible === false;
172
+ let ieq, ieqSwitch;
140
173
  if(hasIndoor) {
141
- const ieq = this._parent.map.indoorEqual;
142
- parts.push(html`
174
+ ieq = this._parent.map.indoorEqual;
175
+ ieqSwitch = html`
143
176
  <pnx-switch
144
177
  .checked=${ieq && ieq.level !== DISABLED_LEVEL}
145
178
  .disabled=${ieq && ieq.levels.length === 0}
146
179
  @change=${this._onIndoorSwitchChange.bind(this)}
147
- style="display: block; margin: 15px 0;"
148
180
  name="pnx-level-switch"
149
181
  >
150
182
  ${this._parent?._t.pnx.indoor_switch}
151
183
  </pnx-switch>
152
- `);
153
- }
154
-
155
- // Map theme selector
156
- parts.push(html`
157
- <h4>${fa(faPalette)} ${this._parent?._t.pnx.map_theme}</h4>
158
- <select id="pnx-map-theme" style="width: 100%;" @change=${this._onThemeSelect}>
159
- <option value=${MAP_THEMES_STYLES.default.id} .selected=${this.theme === MAP_THEMES_STYLES.default.id}>${this._parent?._t.pnx.map_theme_default}</option>
160
- <option value=${MAP_THEMES_STYLES.age.id} .selected=${this.theme === MAP_THEMES_STYLES.age.id}>${this._parent?._t.pnx.map_theme_age}</option>
161
- <option value=${MAP_THEMES_STYLES.type.id} .selected=${this.theme === MAP_THEMES_STYLES.type.id}>${this._parent?._t.pnx.map_theme_type}</option>
162
- ${this._parent?.map?._hasQualityScore?.() && html`
163
- <option value=${MAP_THEMES_STYLES.score.id} .selected=${this.theme === MAP_THEMES_STYLES.score.id}>${this._parent?._t.pnx.map_theme_score}</option>
164
- <option value=${MAP_THEMES_STYLES.gps.id} .selected=${this.theme === MAP_THEMES_STYLES.gps.id}>${this._parent?._t.pnx.map_theme_gps}</option>
165
- `}
166
- </select>
167
- `);
168
-
169
- // Map legend
170
- parts.push(html`<div class=${classMap({"legend": true, "style-v2": isV2})}>
171
- ${this.theme === MAP_THEMES_STYLES.age.id ? html`
172
- <div>
184
+ `;
185
+ }
186
+ const isSmall = this._parent?.isWidthSmall();
187
+ const parentClose = () => this.parentNode.close();
188
+
189
+ return html`
190
+ ${isSmall ? nothing : html`
191
+ <pnx-button
192
+ class="btn-close"
193
+ kind="inline"
194
+ size="l"
195
+ @click=${parentClose}
196
+ >
197
+ ${fa(faXmark)}
198
+ </pnx-button>
199
+ `}
200
+
201
+ <div class="pnx-panel map-layers">
202
+ <div class="map-layers-blocks">
203
+ <div class="map-layers-block">
204
+ <h4>${fa(faPalette)} ${this._parent?._t.pnx.map_theme}</h4>
205
+ <pnx-map-theme ._parent=${this._parent}></pnx-map-theme>
206
+ </div>
207
+
208
+ ${ieq && this._parent?.isWidthSmall() ? ieqSwitch : nothing}
209
+
210
+ ${this._parent?.mapStyleComposer?.hasManyBasemaps?.() ? html`
211
+ <div class="map-layers-block map-layers-block-bg">
212
+ <h4>${fa(faEarthEurope)} ${this._parent?._t.pnx.map_background}</h4>
213
+ <pnx-map-background ._parent=${this._parent}></pnx-map-background>
214
+ </div>
215
+ ` : nothing}
216
+ </div>
217
+
218
+ ${ieq && !this._parent?.isWidthSmall() ? ieqSwitch : nothing}
219
+ </div>
220
+
221
+ <div class=${classMap({
222
+ "pnx-panel": true,
223
+ "legend": true,
224
+ "style-v2": isV2,
225
+ "pnx-hidden": this.theme === MAP_THEMES_STYLES.default.id,
226
+ })}>
227
+ ${this.theme === MAP_THEMES_STYLES.age.id ? html`
173
228
  <div class="legend-entry">
174
229
  <span class="legend-color" style="background-color: ${COLORS["PALETTE_4"]}"></span>
175
230
  ${this._parent?._t.pnx["map_theme_age_4"]}
@@ -178,8 +233,6 @@ export default class MapLayers extends LitElement {
178
233
  <span class="legend-color" style="background-color: ${COLORS["PALETTE_3"]}"></span>
179
234
  ${this._parent?._t.pnx["map_theme_age_3"]}
180
235
  </div>
181
- </div>
182
- <div>
183
236
  <div class="legend-entry">
184
237
  <span class="legend-color" style="background-color: ${COLORS["PALETTE_2"]}"></span>
185
238
  ${this._parent?._t.pnx["map_theme_age_2"]}
@@ -188,30 +241,31 @@ export default class MapLayers extends LitElement {
188
241
  <span class="legend-color" style="background-color: ${COLORS["PALETTE_1"]}"></span>
189
242
  ${this._parent?._t.pnx["map_theme_age_1"]}
190
243
  </div>
191
- </div>` : nothing}
192
-
193
- ${this.theme === MAP_THEMES_STYLES.type.id ? html`
194
- <div class="legend-entry">
195
- <span class="legend-color" style="background-color: ${COLORS.QUALI_1}"></span>
196
- ${this._parent?._t.pnx.picture_360}
197
- </div>
198
- <div class="legend-entry">
199
- <span class="legend-color" style="background-color: ${COLORS.QUALI_2}"></span>
200
- ${this._parent?._t.pnx.picture_flat}
201
- </div>` : nothing}
202
-
203
- ${this.theme === MAP_THEMES_STYLES.score.id ? html`<div>
204
- <pnx-quality-score></pnx-quality-score>
205
- <pnx-button
206
- title="${this._parent?._t.pnx.metadata_quality_help}"
207
- kind="superinline"
208
- @click=${() => this._parent?._showQualityScoreDoc()}
209
- >
210
- ${fa(faInfoCircle)}
211
- </pnx-button></div>` : nothing}
244
+ ` : nothing}
212
245
 
213
- ${this.theme === MAP_THEMES_STYLES.gps.id ? html`
214
- <div>
246
+ ${this.theme === MAP_THEMES_STYLES.type.id ? html`
247
+ <div class="legend-entry">
248
+ <span class="legend-color" style="background-color: ${COLORS.QUALI_1}"></span>
249
+ ${this._parent?._t.pnx.picture_360}
250
+ </div>
251
+ <div class="legend-entry">
252
+ <span class="legend-color" style="background-color: ${COLORS.QUALI_2}"></span>
253
+ ${this._parent?._t.pnx.picture_flat}
254
+ </div>
255
+ ` : nothing}
256
+
257
+ ${this.theme === MAP_THEMES_STYLES.score.id ? html`
258
+ <pnx-quality-score></pnx-quality-score>
259
+ <pnx-button
260
+ title="${this._parent?._t.pnx.metadata_quality_help}"
261
+ kind="superinline"
262
+ @click=${() => this._parent?._showQualityScoreDoc()}
263
+ >
264
+ ${fa(faInfoCircle)}
265
+ </pnx-button>
266
+ ` : nothing}
267
+
268
+ ${this.theme === MAP_THEMES_STYLES.gps.id ? html`
215
269
  <div class="legend-entry">
216
270
  <span class="legend-color" style="background-color: ${GPS_VALUES[0].color}"></span>
217
271
  ${GPS_VALUES[0].label}
@@ -224,8 +278,6 @@ export default class MapLayers extends LitElement {
224
278
  <span class="legend-color" style="background-color: ${GPS_VALUES[4].color}"></span>
225
279
  ${GPS_VALUES[4].label}
226
280
  </div>
227
- </div>
228
- <div>
229
281
  <div class="legend-entry">
230
282
  <span class="legend-color" style="background-color: ${GPS_VALUES[1].color}"></span>
231
283
  ${GPS_VALUES[1].label}
@@ -234,10 +286,9 @@ export default class MapLayers extends LitElement {
234
286
  <span class="legend-color" style="background-color: ${GPS_VALUES[3].color}"></span>
235
287
  ${GPS_VALUES[3].label}
236
288
  </div>
237
- </div>` : nothing}
238
- </div>`);
239
-
240
- return parts;
289
+ ` : nothing}
290
+ </div>
291
+ `;
241
292
  }
242
293
  }
243
294
 
@@ -0,0 +1,186 @@
1
+ import { LitElement, css, html } from "lit";
2
+ import { onceParentAvailable } from "../../utils/widgets.js";
3
+ import { MAP_THEMES_STYLES } from "../../utils/map.js";
4
+ import { COLORS, GPS_VALUES, QUALITYSCORE_VALUES } from "../../utils/utils.js";
5
+
6
+ /**
7
+ * Map Theme menu allows user to select map colouring scheme.
8
+ * @class Panoramax.components.menus.MapTheme
9
+ * @element pnx-map-theme
10
+ * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
11
+ * @example
12
+ * ```html
13
+ * <pnx-map-theme _parent=${viewer} />
14
+ * ```
15
+ */
16
+ export default class MapTheme extends LitElement {
17
+ /** @private */
18
+ static styles = css`
19
+ :host {
20
+ justify-content: space-evenly;
21
+ box-sizing: border-box;
22
+ display: flex;
23
+ }
24
+ input { display: none; }
25
+ label {
26
+ cursor: pointer;
27
+ display: flex;
28
+ flex-direction: column;
29
+ align-items: center;
30
+ gap: 3px;
31
+ font-size: 0.7rem;
32
+ color: var(--grey-dark);
33
+ width: 50px;
34
+ text-align: center;
35
+ }
36
+
37
+ .colors-scheme {
38
+ width: 40px;
39
+ height: 40px;
40
+ border-radius: 22px;
41
+ vertical-align: middle;
42
+ border: 2px solid var(--widget-bg);
43
+ display: flex;
44
+ flex-direction: row;
45
+ overflow: hidden;
46
+ }
47
+
48
+ @media screen and (max-width: 576px) {
49
+ label {
50
+ width: 42px;
51
+ font-size: 0.6rem;
52
+ }
53
+
54
+ .colors-scheme {
55
+ width: 32px;
56
+ height: 32px;
57
+ }
58
+ }
59
+
60
+ .colors-scheme .color-entry {
61
+ display: block;
62
+ width: 100%;
63
+ height: 100%;
64
+ }
65
+
66
+ input:checked + label .colors-scheme {
67
+ outline: 3px solid var(--widget-border-btn);
68
+ }
69
+ `;
70
+
71
+ /** @private */
72
+ static properties = {
73
+ theme: {state: true},
74
+ };
75
+
76
+ /** @private */
77
+ connectedCallback() {
78
+ super.connectedCallback();
79
+
80
+ onceParentAvailable(this).then(() => this._parent?.onceMapReady?.().then(() => {
81
+ this.requestUpdate();
82
+ this._parent.mapStyleComposer?.addEventListener("theme-changed", e => this.theme = e.detail.theme);
83
+ this.theme = this._parent.mapStyleComposer.panoramaxTheme;
84
+ }));
85
+ }
86
+
87
+ /** @private */
88
+ _onThemeSelect(e) {
89
+ this.theme = e.target.value;
90
+ this._parent?.mapStyleComposer.setPanoramaxTheme(this.theme);
91
+ }
92
+
93
+ /** @private */
94
+ render() {
95
+ const isSmall = this._parent?.isWidthSmall();
96
+
97
+ return html`
98
+ <input
99
+ type="radio"
100
+ id="pnx-map-theme-default"
101
+ name="pnx-map-theme"
102
+ value=${MAP_THEMES_STYLES.default.id}
103
+ @change=${this._onThemeSelect}
104
+ .checked=${this.theme === MAP_THEMES_STYLES.default.id}
105
+ />
106
+ <label for="pnx-map-theme-default">
107
+ <div class="colors-scheme">
108
+ <span class="color-entry" style="background-color: ${COLORS.BASE}"></span>
109
+ </div>
110
+ ${isSmall ? this._parent?._t.pnx.map_theme_default_short : this._parent?._t.pnx.map_theme_default}
111
+ </label>
112
+
113
+ <input
114
+ type="radio"
115
+ id="pnx-map-theme-age"
116
+ name="pnx-map-theme"
117
+ value=${MAP_THEMES_STYLES.age.id}
118
+ @change=${this._onThemeSelect}
119
+ .checked=${this.theme === MAP_THEMES_STYLES.age.id}
120
+ />
121
+ <label for="pnx-map-theme-age">
122
+ <div class="colors-scheme">
123
+ <span class="color-entry" style="background-color: ${COLORS.PALETTE_4}"></span>
124
+ <span class="color-entry" style="background-color: ${COLORS.PALETTE_3}"></span>
125
+ <span class="color-entry" style="background-color: ${COLORS.PALETTE_2}"></span>
126
+ <span class="color-entry" style="background-color: ${COLORS.PALETTE_1}"></span>
127
+ </div>
128
+ ${isSmall ? this._parent?._t.pnx.map_theme_age_short : this._parent?._t.pnx.map_theme_age}
129
+ </label>
130
+
131
+ <input
132
+ type="radio"
133
+ id="pnx-map-theme-type"
134
+ name="pnx-map-theme"
135
+ value=${MAP_THEMES_STYLES.type.id}
136
+ @change=${this._onThemeSelect}
137
+ .checked=${this.theme === MAP_THEMES_STYLES.type.id}
138
+ />
139
+ <label for="pnx-map-theme-type">
140
+ <div class="colors-scheme">
141
+ <span class="color-entry" style="background-color: ${COLORS.QUALI_1}"></span>
142
+ <span class="color-entry" style="background-color: ${COLORS.QUALI_2}"></span>
143
+ </div>
144
+ ${isSmall ? this._parent?._t.pnx.map_theme_type_short : this._parent?._t.pnx.map_theme_type}
145
+ </label>
146
+
147
+ ${this._parent?.map?._hasQualityScore?.() && html`
148
+ <input
149
+ type="radio"
150
+ id="pnx-map-theme-score"
151
+ name="pnx-map-theme"
152
+ value=${MAP_THEMES_STYLES.score.id}
153
+ @change=${this._onThemeSelect}
154
+ .checked=${this.theme === MAP_THEMES_STYLES.score.id}
155
+ />
156
+ <label for="pnx-map-theme-score">
157
+ <div class="colors-scheme">
158
+ ${QUALITYSCORE_VALUES.map(qv => html`
159
+ <span class="color-entry" style="background-color: ${qv.color}"></span>
160
+ `)}
161
+ </div>
162
+ ${isSmall ? this._parent?._t.pnx.map_theme_score_short : this._parent?._t.pnx.map_theme_score}
163
+ </label>
164
+
165
+ <input
166
+ type="radio"
167
+ id="pnx-map-theme-gps"
168
+ name="pnx-map-theme"
169
+ value=${MAP_THEMES_STYLES.gps.id}
170
+ @change=${this._onThemeSelect}
171
+ .checked=${this.theme === MAP_THEMES_STYLES.gps.id}
172
+ />
173
+ <label for="pnx-map-theme-gps">
174
+ <div class="colors-scheme">
175
+ <span class="color-entry" style="background-color: ${GPS_VALUES[0].color}"></span>
176
+ <span class="color-entry" style="background-color: ${GPS_VALUES[2].color}"></span>
177
+ <span class="color-entry" style="background-color: ${GPS_VALUES[4].color}"></span>
178
+ </div>
179
+ ${isSmall ? this._parent?._t.pnx.map_theme_gps_short : this._parent?._t.pnx.map_theme_gps}
180
+ </label>
181
+ `}
182
+ `;
183
+ }
184
+ }
185
+
186
+ customElements.define("pnx-map-theme", MapTheme);
@@ -8,6 +8,7 @@ export {default as MapBackground} from "./MapBackground.js";
8
8
  export {default as MapFilters} from "./MapFilters.js";
9
9
  export {default as MapLayers} from "./MapLayers.js";
10
10
  export {default as MapLegend} from "./MapLegend.js";
11
+ export {default as MapTheme} from "./MapTheme.js";
11
12
  export {default as MiniPictureLegend} from "./MiniPictureLegend.js";
12
13
  export {default as PictureLegend} from "./PictureLegend.js";
13
14
  export {default as PictureMetadata} from "./PictureMetadata.js";
@@ -5,7 +5,7 @@ export const panel = css`
5
5
  .pnx-panel {
6
6
  position: absolute;
7
7
  transition: opacity 0.2s 0.1s;
8
- border-radius: 25px;
8
+ border-radius: 20px;
9
9
  border: 1px solid var(--widget-border-div);
10
10
  background-color: var(--widget-bg);
11
11
  color: var(--widget-font);
@@ -30,6 +30,11 @@ export default class TogglableGroup extends LitElement {
30
30
 
31
31
  .pnx-panel { z-index: 130; }
32
32
  .pnx-panel-fixed { position: fixed; }
33
+
34
+ .pnx-panel.pnx-panel-nobg {
35
+ border: none;
36
+ background: none;
37
+ }
33
38
  ` ];
34
39
 
35
40
  /**
@@ -37,10 +42,14 @@ export default class TogglableGroup extends LitElement {
37
42
  * @memberof Panoramax.components.ui.TogglableGroup#
38
43
  * @type {Object}
39
44
  * @property {string} [padded] If set, adds a 15px padding to the menu panel.
45
+ * @property {boolean} [nobg] If set, removes default panel background.
46
+ * @property {boolean} [over-button=false] If set, panel shows up over button (to reduce taken space)
40
47
  */
41
48
  static properties = {
42
49
  _opened: {state: true},
43
50
  padded: {type: String},
51
+ nobg: {type: Boolean},
52
+ "over-button": {type: Boolean},
44
53
  };
45
54
 
46
55
  constructor() {
@@ -111,11 +120,11 @@ export default class TogglableGroup extends LitElement {
111
120
 
112
121
  // No overflow = space a bit under button
113
122
  if(fitsWidth && fitsHeight) {
114
- menu.style.top = `${btnRect.bottom+btnMenuMargin}px`;
123
+ menu.style.top = this["over-button"] ? `${btnRect.top}px` : `${btnRect.bottom+btnMenuMargin}px`;
115
124
  }
116
125
  // Overflows width+height = put at button's top+left
117
126
  else if(!fitsWidth && !fitsHeight) {
118
- menu.style.right = `${window.innerWidth - btnRect.left + btnMenuMargin}px`;
127
+ menu.style.right = this["over-button"] ? `${window.innerWidth - btnRect.right}px` : `${window.innerWidth - btnRect.left + btnMenuMargin}px`;
119
128
  menu.style.bottom = `${window.innerHeight - btnRect.bottom}px`;
120
129
 
121
130
  // Check if it doesn't overflow on top
@@ -129,12 +138,16 @@ export default class TogglableGroup extends LitElement {
129
138
  // Overflows height = limit height
130
139
  else if(!fitsHeight) {
131
140
  menu.style.bottom = `${borderMargin}px`;
132
- menu.style.top = `${btnRect.bottom+btnMenuMargin}px`;
141
+ menu.style.top = this["over-button"] ? `${btnRect.top}px` : `${btnRect.bottom+btnMenuMargin}px`;
133
142
  menu.style.overflowY = "auto";
134
143
  }
135
144
  // Overflows width = move to left
136
145
  else if(!fitsWidth) {
137
- menu.style.marginTop = `${btnMenuMargin}px`;
146
+ if(this["over-button"]) {
147
+ menu.style.top = `${btnRect.top}px`;
148
+ } else {
149
+ menu.style.marginTop = `${btnMenuMargin}px`;
150
+ }
138
151
  menu.style.right = `${window.innerWidth - btnRect.right}px`;
139
152
  }
140
153
  }
@@ -144,6 +157,7 @@ export default class TogglableGroup extends LitElement {
144
157
  const panelClasses = {
145
158
  "pnx-panel": true,
146
159
  "pnx-panel-fixed": true,
160
+ "pnx-panel-nobg": this.nobg,
147
161
  "pnx-hidden": !this._opened,
148
162
  "pnx-padded": this.padded !== "false",
149
163
  };
@@ -1,5 +1,5 @@
1
1
  import { LitElement, html, nothing } from "lit";
2
- import { fa, onceParentAvailable } from "../../../utils/widgets.js";
2
+ import { fa, onceParentAvailable, createWebComp } from "../../../utils/widgets.js";
3
3
  import {
4
4
  faChevronDown, faLayerGroup, faXmark
5
5
  } from "@fortawesome/free-solid-svg-icons";
@@ -43,29 +43,51 @@ export default class MapLayersButton extends LitElement {
43
43
  }));
44
44
  }
45
45
 
46
+ /** @private */
47
+ _toggleDrawer() {
48
+ if(this._parent?.isBottomDrawerVisible?.()) {
49
+ const bottomDrawerContent = this._parent.bottomDrawer.shadowRoot.querySelector("slot")?.assignedNodes();
50
+ if(bottomDrawerContent.find(c => c.tagName.toLowerCase() === "pnx-map-layers-menu")) {
51
+ this._parent?.setBottomDrawer(false);
52
+ return;
53
+ }
54
+ }
55
+
56
+ this._parent?.setBottomDrawer?.(true, [createWebComp(
57
+ "pnx-map-layers-menu",
58
+ { id: "pnx-map-layers-menu", _parent: this._parent }
59
+ )], {autoadjust: true, autoclose: true});
60
+ }
61
+
46
62
  /** @private */
47
63
  render() {
48
- const isSmall = this._parent?.isWidthSmall() || this._parent?.isWidthMedium();
64
+ const isSmallSized = this._parent?.isWidthSmall();
65
+ const isMedSized = this._parent?.isWidthMedium();
49
66
  const resetIcon = fa(faXmark, {styles: {"pointer-events": "auto"}});
50
67
  resetIcon.addEventListener("click", e => {
51
68
  e.stopPropagation();
52
- const menu = this.shadowRoot.querySelector("pnx-map-layers-menu");
53
- menu.shadowRoot.querySelector("#pnx-map-theme").value = "default";
54
- menu._onThemeSelect({target: {value: "default"}});
55
- this.shadowRoot.querySelector("#pnx-widget-map-layers")._opened = false;
69
+ this._parent.mapStyleComposer.setPanoramaxTheme("default");
56
70
  });
57
71
 
58
- return html`
72
+ return isSmallSized ? html`
73
+ <pnx-button kind="flat" size="xl" slot="button" @click=${this._toggleDrawer}>
74
+ ${fa(faLayerGroup)}
75
+ ${this._active ? html`<span class="pnx-active-icon"></span>` : nothing}
76
+ </pnx-button>
77
+ ` : html`
59
78
  <pnx-togglable-group
60
79
  id="pnx-widget-map-layers"
61
80
  class="pnx-print-hidden"
81
+ nobg
82
+ padded="false"
83
+ over-button
62
84
  ._parent=${this._parent}
63
85
  >
64
86
  <pnx-button kind="flat" size="xl" slot="button">
65
87
  ${fa(faLayerGroup)}
66
88
  ${this._active ? html`<span class="pnx-active-icon"></span>` : nothing}
67
- ${isSmall ? nothing : this._parent?._t.pnx.layers}
68
- ${isSmall ? nothing : (this._active ? resetIcon : fa(faChevronDown))}
89
+ ${isMedSized ? nothing : this._parent?._t.pnx.layers}
90
+ ${isMedSized ? nothing : (this._active ? resetIcon : fa(faChevronDown))}
69
91
  </pnx-button>
70
92
  <pnx-map-layers-menu
71
93
  id="pnx-map-layers-menu"