Skip to content
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3f20b07
Add layer loading indicator widget to map
DarianGill Aug 26, 2026
6133d3a
Add tests enforcing layer loading indicator behavior to Map.spec.js a…
DarianGill Aug 26, 2026
0445ab0
Dismiss layer loading widget when a layer fails to show instead of pe…
DarianGill Aug 26, 2026
d7736ef
Add .5s delay to show loading widget to reduce visual noise for fast-…
DarianGill Aug 26, 2026
e5d56f8
Exclude default map layer from loading indicator monitor
DarianGill Aug 27, 2026
d7f6ab0
Make map central loading authority so name loader and loading widget …
DarianGill Aug 28, 2026
841b554
Better encapsulate loading state derivation and ui updates and ensure…
DarianGill Aug 28, 2026
d4a7f97
Extract LayerLoadingCoordinator module to reduce cesium coupling in m…
DarianGill Aug 28, 2026
1da2564
Change loading indicator styling to match scale bar and avoid overlap…
DarianGill Aug 28, 2026
3ee2a69
Stop retrying feature restore path when layer visibility changes
DarianGill Aug 29, 2026
59bfd69
npm run format
DarianGill Aug 31, 2026
e9ef61a
Monitor layer-group collection events for layer loading and url sync
DarianGill Aug 31, 2026
6d0ac9d
Ensure that toggling off a layer clears selected feature from that la…
DarianGill Aug 31, 2026
f7d0cf3
Use json serialization for feature and layer id arrays in ActiveFeatu…
DarianGill Sep 1, 2026
1c403d6
Add a shared display-ready lifecycle API to the base asset model in M…
DarianGill Sep 1, 2026
105f70e
Reveal the aria-live region before mutating its text so the loading m…
DarianGill Sep 1, 2026
0713d3d
npm run format
DarianGill Sep 1, 2026
5b11aee
Update handler for displayReady to handle new side fx.
DarianGill Sep 1, 2026
a7bbfdf
Fix map loading/restore event regressions:
DarianGill Sep 1, 2026
6f62e03
Merge branch 'feature-2636-url-encode-active-feature' into feature-21…
DarianGill Sep 11, 2026
4959189
Gate feature restore interruption logic so that only features contain…
DarianGill Sep 11, 2026
6b905e3
Fix map loading indicator getting stuck for imagery and 3D tile layers
DarianGill Sep 11, 2026
a92521c
Make loading indicator delay 1 second
DarianGill Sep 15, 2026
d9014be
Extract LayerLoadingIndicatorView and add it beneath scale bar in new…
DarianGill Sep 15, 2026
9244391
Smooth scale bar width adjustments by:
DarianGill Sep 15, 2026
b3bc4a1
Make status bar loader transparent by default so it's only visible wh…
DarianGill Sep 17, 2026
ea06fe4
Render layer loading label as html instead of text so it's the same a…
DarianGill Sep 17, 2026
36c499c
Add missing since tags
DarianGill Sep 17, 2026
484c9ec
Raise the draw polygon with every point added so it's always visible …
DarianGill Sep 18, 2026
c61cb97
Ensure that the inline layer label loading icon doesn't jostle the fi…
DarianGill Sep 19, 2026
463a527
Debounce loading message updates for less jitter.
DarianGill Sep 19, 2026
553613d
npm run format
DarianGill Sep 19, 2026
c8aedfe
Remove stale reference to this.clearLayerLoadingIndicatorTimer
DarianGill Sep 22, 2026
be5a705
Use layers loading for message count instead of labels in case there …
DarianGill Sep 22, 2026
9317504
Initialize imagery and 3dtileset tilesLoading to false
DarianGill Sep 22, 2026
39fd897
Tear down status bar before replacing it in renderStatusBar
DarianGill Sep 22, 2026
b8b2c7c
Clear the hidden layer's selected features before clearFeatureRestore…
DarianGill Sep 22, 2026
0d5788a
Call setError() if synchronous creation failures occur in Cesium3DTil…
DarianGill Sep 22, 2026
e545bd8
Add unit test for feature timeout/cancellation path.
DarianGill Sep 22, 2026
500efda
Stop tracking for all assets during CesiumWidget teardown and ensure …
DarianGill Sep 23, 2026
e151863
Fix JSDOC errors
DarianGill Sep 23, 2026
59474aa
Include default base layer in loading indicator and remove test for i…
DarianGill Sep 24, 2026
0c18165
Inline plain string template and extract CLASS_NAMES constant in Laye…
DarianGill Sep 24, 2026
4905a5e
Add properties and desc on MapStatusBarView and extract BASE_CLASS
DarianGill Sep 24, 2026
f3f5622
Remove dead loading:started trigger and css classes
DarianGill Sep 24, 2026
c0ad2e6
Use dot instread of bracket notation now that no-underscore-dangle ha…
DarianGill Sep 24, 2026
f70b8fc
Merge remote-tracking branch 'origin/develop' into feature-2126-layer…
DarianGill Sep 25, 2026
c9549f7
npm run format
DarianGill Sep 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
217 changes: 197 additions & 20 deletions src/css/map-view.css
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,30 @@
--map-width-feature-info: calc(var(--map-width-toolbar) * 1.25);
--map-width-feature-info-wide: calc(var(--map-width-toolbar-wide) * 1.25);
--map-padding-feature-info: 1.5rem;
--map-top-control-height: 2rem;
--map-top-controls-gutter: 1rem;
--map-top-controls-left-reserved: calc(
var(--map-toolbar-link-width) + (2 * var(--map-size-toolbar-link-margin)) +
var(--map-top-controls-gutter)
);
/* Worst-case width of everything in the status bar except the scale bar graphic
itself: padding, the signed 5-decimal lat + lng (with their reserved digit widths),
and the longest realistic distance label. */
--map-scale-bar-base-width: 18rem;
/* The scale bar graphic's max drawn length (see `maxBarWidth` in ScaleBarView). */
--map-scale-bar-max-bar-width: 6.25rem;
/* Live pixel width of the scale bar graphic (`.scale-bar__bar`), mirrored here by
ScaleBarView/MapStatusBarView on every update. The status bar's own width tracks
this exactly (see `.map-status-bar` below) so it grows/shrinks by the same amount,
in sync with the bar, and -- being a plain length rather than content-driven
auto-sizing -- animates smoothly with `transition: width` in every browser. */
--map-status-bar-bar-width: 0px;
--map-scale-bar-reserved-width: calc(
var(--map-scale-bar-base-width) + var(--map-scale-bar-max-bar-width)
);
--map-top-controls-right-reserved: calc(
var(--map-scale-bar-reserved-width) + var(--map-top-controls-gutter)
);
/* SHADOWS */
--map-shadow-md: var(
--portal-shadow-md,
Expand Down Expand Up @@ -331,7 +355,12 @@
right: 1rem;
bottom: 1rem;
min-height: 10rem;
overflow: hidden;
/* Reserve room at the top for the status bar (its 1rem top offset, plus its own
height doubled to cover the loading row's expanded state) plus a gap, so a tall
feature-info panel can never grow up far enough to cover the loading indicator. */
max-height: calc(100% - 3rem - (2 * var(--map-top-control-height)));
overflow-y: auto;
overflow-x: hidden;
/* required to be placed above map widget in firefox: */
z-index: var(--map-z-index-feature-info);

Expand Down Expand Up @@ -426,32 +455,58 @@

/*****************************************************************************************
*
* Scale Bar
* Scale Bar & Layer Loading Indicator
*
* The legend that shows both the coordinates of the mouse and a scale bar
* The map-status-bar is the box in the top-right of the map that contains the scale
* bar (mouse coordinates + distance scale) plus a loading row that smoothly expands
* beneath it while layers are loading.
*
*/

.scale-bar {
width: max-content;
min-width: 12rem;
min-height: 2rem;
.map-status-bar {
/* Everything except the scale bar graphic is reserved at a fixed (worst-case)
width, and the live bar width is added on top -- so the box grows/shrinks by
exactly as much as the bar does. Because both are plain lengths (not
content-driven auto-sizing), this transitions smoothly with `transition: width`
in every browser, unlike animating to/from an auto/max-content size. */
width: calc(
var(--map-scale-bar-base-width) + var(--map-status-bar-bar-width, 0px)
);
box-shadow: var(--map-shadow-md);
background: var(--portal-col-neutral-1, var(--map-col-bkg__deprecate));
border-radius: var(--map-border-radius-small);
color: var(--portal-col-neutral-5, var(--map-col-text__deprecate));
font-size: 0.8rem;
box-sizing: border-box;
position: absolute;
top: 1rem;
right: 1rem;
overflow: hidden;
/* Matches `.scale-bar__bar`'s own transition so the box's edge and the bar's
edge move in lockstep instead of drifting apart mid-animation. */
transition: width 0.3s ease-in-out;
/* required to be placed above map widget in firefox: */
z-index: var(--map-z-index-base);
}

.scale-bar {
height: var(--map-top-control-height);
min-height: var(--map-top-control-height);
padding: 0.18rem 0.8rem;
display: grid;
grid-template-rows: 100%;
grid-template-columns: auto auto;
gap: 1rem;
align-items: center;
position: absolute;
top: 1rem;
right: 1rem;
/* required to be placed above map widget in firefox: */
z-index: var(--map-z-index-base);
box-sizing: border-box;
/* Never wrap to a second line at narrow viewport widths -- content that doesn't
fit is clipped by the (fixed-width) `.map-status-bar`'s `overflow: hidden` instead. */
white-space: nowrap;
/* Without this, the fixed-width box's leftover space stretches evenly across both
auto columns, so the coordinates column grows/shrinks (moving lat/lng) whenever the
scale column's own content changes width. `start` keeps every column sized to its
own content and puts the leftover space after the last column instead. */
justify-content: start;
}

/* __coordinates contains __longitude, __latitude, and __elevation */
Expand All @@ -462,6 +517,10 @@
grid-template-columns: auto auto auto;
gap: 0.5rem;
align-items: center;
/* Keep lat/lng/elevation pinned to their own content width so the elevation column
(whose value is added/cleared independently) can never shift lat/lng leftward or
rightward -- see the matching comment on `.scale-bar`. */
justify-content: start;
}

/* The elements that contain the current coordinates */
Expand All @@ -470,6 +529,26 @@
font-weight: 600;
}

/* Tabular numerals (equal-width digits, when the font supports the feature) plus a
reserved minimum width (long enough for e.g. "-179.12345") keep the coordinate boxes
from constantly resizing/jittering as the digits change while panning. Left-aligned
(the default) so the value sits right up against its label, with any reserved-but-
unused width trailing after the digits instead of showing as a gap before them. */

.scale-bar__coord--latitude {
display: inline-block;
/* Reserves enough room for the longest possible value, e.g. "-90.12345" (9 chars) */
min-width: 9ch;
font-variant-numeric: tabular-nums;
}

.scale-bar__coord--longitude {
display: inline-block;
/* Reserves enough room for the longest possible value, e.g. "-180.12345" (10 chars) */
min-width: 10ch;
font-variant-numeric: tabular-nums;
}

/* The __scale element contains __bar and __distance */

.scale-bar__scale {
Expand All @@ -489,6 +568,83 @@ represents 1 unit of the given distance measurement. */
background-color: var(--portal-col-neutral-4, var(--map-col-text__deprecate));
}

/* The loading row is collapsed (zero height) by default and smoothly expands open
when a layer takes longer than a second to load. The 0fr/1fr grid-row trick animates
to/from an intrinsic content height without needing to measure pixels in JS. */

.map-status-bar__loading-row {
display: grid;
grid-template-rows: 0fr;
transition: grid-template-rows 0.35s ease;
}

.map-status-bar--loading-expanded .map-status-bar__loading-row {
grid-template-rows: 1fr;
}

.map-status-bar__loading-row-inner {
min-height: 0;
overflow: hidden;
/* Transparent until expanded -- a visible border here would still paint as a
thin line even while the row is collapsed to 0 height, since border-width isn't
squeezed by the 0fr grid row the way content height is. */
border-top: 1px solid transparent;
transition: border-color 0.2s ease;
}

.map-status-bar--loading-expanded .map-status-bar__loading-row-inner {
border-top-color: var(--portal-col-primary-2);
}

.map-status-bar__loading-bar {
position: relative;
height: 0.2rem;
width: 100%;
overflow: hidden;
background: var(
--portal-col-primary-2,
var(--map-col-bkg-lighter__deprecate)
);
}

.map-status-bar__loading-bar::after {
content: "";
position: absolute;
inset: 0;
width: 35%;
background: var(--portal-col-primary-6, var(--map-col-highlight__deprecate));
animation: map-status-bar-loading-bar 1.5s ease-in-out infinite;
}

.map-status-bar__loading-message {
display: flex;
align-items: center;
min-height: calc(var(--map-top-control-height) - 0.2rem - 1px);
padding: 0 0.8rem;
font-size: 0.8rem;
font-weight: 500;
letter-spacing: 0.01em;
}

.map-status-bar__loading-text {
/* Allows this flex item to shrink below its content size so the ellipsis below
can actually kick in once the (now fixed-width) status bar runs out of room. */
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

@keyframes map-status-bar-loading-bar {
0% {
transform: translateX(-120%);
}

100% {
transform: translateX(320%);
}
}

/*****************************************************************************************
*
* Toolbar
Expand Down Expand Up @@ -944,8 +1100,8 @@ represents 1 unit of the given distance measurement. */

.list-item__settings {
/* Show button when layer is hovered. */
display: flex;
border: 1px solid var(--portal-col-neutral-4);
visibility: visible;
border-color: var(--portal-col-neutral-4);

/* Use the same style on button hover and when selected. */
&.list-item--selected,
Expand Down Expand Up @@ -975,8 +1131,8 @@ represents 1 unit of the given distance measurement. */

.list-item__settings {
/* Show button when layer is shown. */
display: flex;
border: 1px solid var(--portal-col-primary-2);
visibility: visible;
border-color: var(--portal-col-primary-2);
}
}

Expand All @@ -985,10 +1141,14 @@ represents 1 unit of the given distance measurement. */
}

.list-item__settings {
/* By default, don't show button. */
display: none;
/* Always reserve this column's width (max-content) so hovering/selecting
a layer never resizes it and shifts the label/filter icon; hide via
visibility (not display) and keep a same-size transparent border. */
display: flex;
visibility: hidden;
align-items: center;
border-radius: var(--map-border-radius-small);
border: 1px solid transparent;

.list-item__settings-toggle {
font-size: 0.85rem;
Expand All @@ -1004,9 +1164,9 @@ represents 1 unit of the given distance measurement. */
/* Use the same style on button hover and when selected. */
&.list-item--selected,
&:hover {
display: flex;
visibility: visible;
background-color: var(--portal-col-primary-1, #15324e);
border: 1px solid var(--portal-col-primary-1, #15324e);
border-color: var(--portal-col-primary-1, #15324e);

.list-item__settings-toggle {
color: var(--portal-col-primary-6);
Expand All @@ -1029,6 +1189,23 @@ represents 1 unit of the given distance measurement. */
gap: 4px;
}

.list-item__status-icon {
/* fixed footprint so the loading/error icon appearing or disappearing never
shifts sibling elements like the filter icon */
display: flex;
align-items: center;
justify-content: center;
width: 1rem;
height: 1rem;
flex: 0 0 auto;
opacity: 0.6;
visibility: hidden;
}

.list-item__status-icon--visible {
visibility: visible;
}

.list-item__highlighted-text {
background-color: var(--portal-col-highlight-2, rgba(30, 127, 196, 0.5));
}
Expand Down
Loading
Loading