Skip to content

Commit 6092796

Browse files
aleksprogergithub-actions[bot]
authored andcommitted
Allign indoor control styling with other controls (internal-9849)
GitOrigin-RevId: bd895ed77bfaa5a8b98de726ea3c9b39a28bcd90
1 parent 138d351 commit 6092796

8 files changed

Lines changed: 245 additions & 105 deletions

File tree

debug/indoor.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
<script>
3333
var map = window.map = new mapboxgl.Map({
3434
container: 'map',
35-
devtools: true,
3635
zoom: 17.5,
3736
bearing: -15,
3837
pitch: 50,
@@ -41,6 +40,7 @@
4140
});
4241

4342
map.addControl(new mapboxgl.NavigationControl());
43+
map.addControl(new mapboxgl.IndoorControl());
4444
map.addControl(new mapboxgl.AttributionControl());
4545

4646
map.setStyle(style);

src/css/mapbox-gl.css

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@
100100
}
101101

102102
.mapboxgl-ctrl-group button {
103-
width: 29px;
104-
height: 29px;
103+
width: 32px;
104+
height: 32px;
105105
display: block;
106106
padding: 0;
107107
outline: none;
@@ -160,7 +160,7 @@
160160
}
161161

162162
.mapboxgl-ctrl button:not(:disabled):hover {
163-
background-color: rgb(0 0 0 / 5%);
163+
background-color: #eee;
164164
}
165165

166166
.mapboxgl-ctrl-group button:focus:focus-visible {
@@ -248,6 +248,17 @@
248248
}
249249
}
250250

251+
.mapboxgl-ctrl button.mapboxgl-ctrl-arrow-up .mapboxgl-ctrl-icon {
252+
background-image: svg-load("svg/mapboxgl-ctrl-arrow-up.svg", fill: #333);
253+
background-size: 18px 18px;
254+
}
255+
256+
.mapboxgl-ctrl button.mapboxgl-ctrl-arrow-down .mapboxgl-ctrl-icon {
257+
background-image: svg-load("svg/mapboxgl-ctrl-arrow-down.svg", fill: #333);
258+
background-size: 18px 18px;
259+
}
260+
261+
251262
@svg-load ctrl-geolocate url("svg/mapboxgl-ctrl-geolocate.svg") {
252263
fill: #333;
253264
#stroke { display: none; }
@@ -304,15 +315,6 @@
304315
background-image: svg-inline(ctrl-geolocate);
305316
}
306317

307-
.mapboxgl-ctrl button.mapboxgl-ctrl-buildings-toggle .mapboxgl-ctrl-icon {
308-
background-image: svg-load("svg/mapboxgl-ctrl-buildings-toggle.svg");
309-
background-size: 26px 26px;
310-
}
311-
312-
.mapboxgl-ctrl button.mapboxgl-ctrl-buildings-toggle.mapboxgl-ctrl-level-button-selected .mapboxgl-ctrl-icon {
313-
filter: invert(1) brightness(1);
314-
}
315-
316318
.mapboxgl-ctrl button.mapboxgl-ctrl-geolocate:disabled .mapboxgl-ctrl-icon {
317319
background-image: svg-inline(ctrl-geolocate-disabled);
318320
}
@@ -652,7 +654,7 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact {
652654
}
653655

654656
.mapboxgl-popup-close-button:hover {
655-
background-color: rgb(0 0 0 / 5%);
657+
background-color: #eee;
656658
}
657659

658660
.mapboxgl-popup-content {
@@ -834,45 +836,17 @@ a.mapboxgl-ctrl-logo.mapboxgl-compact {
834836
touch-action: pan-x pan-y;
835837
}
836838

837-
.mapboxgl-ctrl-separator {
838-
height: 1px;
839-
background-color: #e0e0e0;
840-
}
841839

842840
.mapboxgl-ctrl button.mapboxgl-ctrl-level-button {
843-
color: #333;
844-
font-size: 18px;
845-
width: 50px;
846-
height: 50px;
847841
font-weight: bold;
848-
text-align: center;
849-
line-height: normal;
850-
padding: 0;
851-
display: flex;
852-
align-items: center;
853-
justify-content: center;
854-
}
855-
856-
.mapboxgl-ctrl button.mapboxgl-ctrl-level-button:first-child {
857-
border-top-left-radius: 8px;
858-
border-top-right-radius: 8px;
859-
}
860-
861-
.mapboxgl-ctrl button.mapboxgl-ctrl-level-button:last-child {
862-
border-bottom-left-radius: 8px;
863-
border-bottom-right-radius: 8px;
864-
}
865-
866-
.mapboxgl-ctrl button.mapboxgl-ctrl-level-button:hover {
867-
background-color: #f5f5f5;
842+
font-size: 16px;
868843
}
869844

870845
.mapboxgl-ctrl button.mapboxgl-ctrl-level-button-selected {
871-
background-color: #4a5568;
872-
color: #fff;
846+
background-color: #ccc;
847+
color: #000;
873848
}
874849

875850
.mapboxgl-ctrl button.mapboxgl-ctrl-level-button-selected:hover {
876-
background-color: #2d3748;
851+
background-color: #ccc;
877852
}
878-
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

src/css/svg/mapboxgl-ctrl-buildings-toggle.svg

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/style-spec/expression/definitions/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,9 @@ CompoundExpression.register(expressions, {
270270
BooleanType,
271271
varargs(StringType),
272272
(ctx, args) => {
273-
const hasActiveFloors = ctx.globals.activeFloors && ctx.globals.activeFloors.size > 0;
273+
const hasActiveFloors = ctx.globals && ctx.globals.activeFloors && ctx.globals.activeFloors.size > 0;
274274
if (!hasActiveFloors) { return false; }
275+
if (args.length === 0) { return true; }
275276
const floorIds: Set<string> = ctx.globals.activeFloors;
276277
return args.some(arg => {
277278
const value = arg.evaluate(ctx) as string;

src/ui/control/indoor_control.ts

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import * as DOM from '../../util/dom';
22
import {bindAll} from '../../util/util';
33

44
import type {Map, ControlPosition, IControl} from '../map';
5-
import type {IndoorControlModel, IndoorControlFloor} from '../../style/indoor_data';
5+
import type {IndoorControlModel} from '../../style/indoor_data';
6+
const VISIBLE_FLOORS = 3;
67

78
/**
89
* An `IndoorControl` control presents the map's indoor floors.
@@ -18,11 +19,12 @@ class IndoorControl implements IControl {
1819
_map: Map | null;
1920
_container: HTMLElement | null;
2021
_model: IndoorControlModel | null;
22+
_visibleFloorStart: number;
2123

2224
constructor() {
23-
bindAll(['_onIndoorUpdate', '_onStyleData'], this);
25+
bindAll(['_onIndoorUpdate', '_onStyleData', '_scrollUp', '_scrollDown'], this);
26+
this._visibleFloorStart = 0;
2427
}
25-
2628
onAdd(map: Map): HTMLElement {
2729
this._map = map;
2830
this._container = DOM.create('div', 'mapboxgl-ctrl mapboxgl-ctrl-group');
@@ -31,11 +33,9 @@ class IndoorControl implements IControl {
3133
this._updateConnection();
3234
return this._container;
3335
}
34-
3536
_onStyleData() {
3637
this._updateConnection();
3738
}
38-
3939
_updateConnection() {
4040
if (this._map && this._map.style && this._map.style.indoorManager) {
4141
const manager = this._map.style.indoorManager;
@@ -44,24 +44,16 @@ class IndoorControl implements IControl {
4444
this._onIndoorUpdate(manager.getControlState());
4545
}
4646
}
47-
4847
_createButton(className: string, fn: (e: Event) => unknown): HTMLButtonElement {
4948
const a = DOM.create('button', className, this._container);
5049
a.type = 'button';
5150
a.addEventListener('click', fn);
5251
return a;
5352
}
54-
55-
_createSeparator(): HTMLElement {
56-
return DOM.create('div', 'mapboxgl-ctrl-separator', this._container);
57-
}
58-
5953
_setButtonTitle(button: HTMLButtonElement, title: string) {
60-
if (!this._map) return;
6154
button.setAttribute('aria-label', title);
6255
button.textContent = title;
6356
}
64-
6557
onRemove() {
6658
if (this._container) {
6759
this._container.remove();
@@ -74,11 +66,9 @@ class IndoorControl implements IControl {
7466
this._map = null;
7567
}
7668
}
77-
7869
getDefaultPosition(): ControlPosition {
7970
return 'top-right';
8071
}
81-
8272
_onIndoorUpdate(model: IndoorControlModel | null) {
8373
if (!model || !model.floors) {
8474
this._model = model;
@@ -88,62 +78,84 @@ class IndoorControl implements IControl {
8878
const oldModel = this._model;
8979
this._model = model;
9080
this._container.style.display = 'inline-block';
91-
if (oldModel) {
92-
Array.from(this._container.children).forEach(child => child.remove());
93-
}
94-
if (model.floors.length > 0) {
95-
this.addBuildingsToggleButton();
96-
this.addCurrentFloors(model.floors, model.activeFloorsVisible);
97-
this._updateBuildingsButtonState();
81+
82+
const floorsChanged = !oldModel || oldModel.floors.length !== model.floors.length || oldModel.floors.some((f, i) => f.id !== model.floors[i].id);
83+
84+
if (floorsChanged) {
85+
this._visibleFloorStart = 0;
9886
}
99-
}
10087

101-
addBuildingsToggleButton() {
102-
const buildingsButton = this._createButton('mapboxgl-ctrl-buildings-toggle', () => {
103-
const map = this._map;
104-
if (this._model && map) {
105-
map._setIndoorActiveFloorsVisibility(!this._model.activeFloorsVisible);
88+
if (model.selectedFloorId) {
89+
const selectedIndex = model.floors.findIndex(f => f.id === model.selectedFloorId);
90+
if (selectedIndex !== -1) {
91+
if (selectedIndex < this._visibleFloorStart) {
92+
this._visibleFloorStart = selectedIndex;
93+
} else if (selectedIndex >= this._visibleFloorStart + VISIBLE_FLOORS) {
94+
this._visibleFloorStart = selectedIndex - (VISIBLE_FLOORS - 1);
95+
}
10696
}
107-
});
108-
DOM.create('span', `mapboxgl-ctrl-icon`, buildingsButton).setAttribute('aria-hidden', 'true');
109-
buildingsButton.classList.add('mapboxgl-ctrl-level-button', 'mapboxgl-ctrl-buildings-toggle');
110-
if (this._model && !this._model.activeFloorsVisible) {
111-
buildingsButton.classList.add('mapboxgl-ctrl-level-button-selected');
11297
}
113-
this._container.append(buildingsButton);
98+
99+
this._render();
114100
}
115101

116-
_updateBuildingsButtonState() {
117-
const buildingsButton = this._container.querySelector('.mapboxgl-ctrl-buildings-toggle');
118-
if (buildingsButton && this._model) {
119-
if (!this._model.activeFloorsVisible) {
120-
buildingsButton.classList.add('mapboxgl-ctrl-level-button-selected');
121-
} else {
122-
buildingsButton.classList.remove('mapboxgl-ctrl-level-button-selected');
102+
_render() {
103+
if (!this._container || !this._model || !this._model.floors) return;
104+
105+
this._container.innerHTML = '';
106+
const floors = this._model.floors;
107+
const totalFloors = floors.length;
108+
109+
if (totalFloors > VISIBLE_FLOORS) {
110+
const upButton = this._createButton('mapboxgl-ctrl-arrow-up', this._scrollUp);
111+
if (this._visibleFloorStart === 0) {
112+
upButton.disabled = true;
123113
}
114+
DOM.create('span', 'mapboxgl-ctrl-icon', upButton).setAttribute('aria-hidden', 'true');
115+
this._container.appendChild(upButton);
124116
}
125-
}
126117

127-
addCurrentFloors(floors: Array<IndoorControlFloor>, showSelectedFloor: boolean) {
128-
for (let i = 0; i < floors.length; i++) {
129-
const floor = floors[i];
118+
const visibleFloors = floors.slice(this._visibleFloorStart, this._visibleFloorStart + VISIBLE_FLOORS);
119+
visibleFloors.forEach(floor => {
130120
const levelButton = this._createButton('mapboxgl-ctrl-level-button', () => {
131-
this._map._selectIndoorFloor(floor.id);
121+
if (this._model && this._model.selectedFloorId === floor.id) return;
122+
if (this._map) {
123+
this._map._setIndoorActiveFloorsVisibility(true);
124+
this._map._selectIndoorFloor(floor.id);
125+
}
132126
});
133-
134127
const floorName = (floor.name || '').trim();
135128
const zIndexText = floor.zIndex.toString();
136129
const buttonTitle = floorName ? Array.from(floorName).slice(0, 3).join('') : zIndexText;
137130
this._setButtonTitle(levelButton, buttonTitle);
138-
if (this._model && floor.id === this._model.selectedFloorId && showSelectedFloor) {
131+
132+
if (this._model && floor.id === this._model.selectedFloorId) {
139133
levelButton.classList.add('mapboxgl-ctrl-level-button-selected');
140134
}
141-
this._container.append(levelButton);
135+
this._container.appendChild(levelButton);
136+
});
142137

143-
// Add separator after each button except the last one
144-
if (i < floors.length - 1) {
145-
this._createSeparator();
138+
if (totalFloors > VISIBLE_FLOORS) {
139+
const downButton = this._createButton('mapboxgl-ctrl-arrow-down', this._scrollDown);
140+
if (this._visibleFloorStart + VISIBLE_FLOORS >= totalFloors) {
141+
downButton.disabled = true;
146142
}
143+
DOM.create('span', 'mapboxgl-ctrl-icon', downButton).setAttribute('aria-hidden', 'true');
144+
this._container.appendChild(downButton);
145+
}
146+
}
147+
148+
_scrollUp() {
149+
if (this._visibleFloorStart > 0) {
150+
this._visibleFloorStart--;
151+
this._render();
152+
}
153+
}
154+
155+
_scrollDown() {
156+
if (this._model && this._model.floors && this._visibleFloorStart + VISIBLE_FLOORS < this._model.floors.length) {
157+
this._visibleFloorStart++;
158+
this._render();
147159
}
148160
}
149161
}

0 commit comments

Comments
 (0)