Skip to content

Add Legend and GeoJSON samples#12

Open
magmoe wants to merge 8 commits intomainfrom
feature/11-new-samples-and-styling
Open

Add Legend and GeoJSON samples#12
magmoe wants to merge 8 commits intomainfrom
feature/11-new-samples-and-styling

Conversation

@magmoe
Copy link
Copy Markdown

@magmoe magmoe commented Mar 31, 2026

Summary

  • Two new Core sample pages: Legend and GeoJSON Layers
  • Fix widget dark mode background and text contrast
  • Fix existing build error in UniqueValueRenderers

New Samples

Legend (/legends) - LegendWidget with three toggleable FeatureLayers using different renderers (SimpleRenderer with
SizeVariable, UniqueValueRenderer, SimpleFillSymbol). Responsive side-by-side layout on wide screens.

GeoJSON Layers (/geojson-layers) - Live USGS earthquake GeoJSON data with magnitude-based size rendering, click
popups, and data source switcher (past month/week/day).

Styling Fix

  • .esri-widget now gets background-color: var(--background-grey-2) and color: var(--text-emphasis) instead of color:
    unset, fixing white widget backgrounds and unreadable text in dark mode across all samples.

Bug Fix

  • UniqueValueRenderers.razor.cs: Replace missing ToUpperFirstChar() extension method with standard string
    manipulation.
Screenshot 2026-03-31 134547 Screenshot 2026-03-31 134615 Screenshot 2026-03-31 142030 Screenshot 2026-03-31 142051

New Core samples:
- Legend: Toggleable layers with LegendWidget, responsive side-by-side layout
- GeoJSON Layers: USGS earthquake data with size variable renderer and popups

Styling fixes:
- Fix esri-widget dark mode background (was white, now matches site theme)
- Fix inline code readability (was orange-red on black, now green on dark gray)

Bug fix:
- Fix UniqueValueRenderers build error (missing ToUpperFirstChar extension)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds new Core sample pages demonstrating the Legend widget and GeoJSON layers, updates shared widget styling for better dark-mode contrast, and fixes a build break in the UniqueValueRenderers sample.

Changes:

  • Added two new sample pages: Legend (/legends) and GeoJSON Layers (/geojson-layers) and linked them in the navigation.
  • Updated shared CSS to apply consistent background/text colors to ArcGIS widgets in dark mode.
  • Replaced a missing string extension method in UniqueValueRenderers.razor.cs with inline string manipulation.

Reviewed changes

Copilot reviewed 5 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
samples/core/dymaptic.GeoBlazor.Core.Sample.Shared/wwwroot/images/legend.svg Adds a nav icon for the new Legend sample.
samples/core/dymaptic.GeoBlazor.Core.Sample.Shared/wwwroot/images/geojson.svg Adds a nav icon for the new GeoJSON sample.
samples/core/dymaptic.GeoBlazor.Core.Sample.Shared/wwwroot/css/site.css Adjusts .esri-widget foreground/background to fix dark-mode contrast.
samples/core/dymaptic.GeoBlazor.Core.Sample.Shared/Shared/NavMenu.razor.cs Registers the two new samples in the left nav.
samples/core/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/UniqueValueRenderers.razor.cs Fixes build by removing dependency on a missing extension method.
samples/core/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/Legends.razor New Legend sample page with toggleable layers and responsive layout.
samples/core/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/GeoJSONLayers.razor New GeoJSON sample page with USGS feed switching, renderer, and popup.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

color: var(--text-emphasis);
background-color: var(--background-grey-2);
}

Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new .esri-widget:not(.esri-feature-table) rule has higher specificity than the .esri-feature-templates / .esri-feature-form rules above it, so it will override those backgrounds and effectively negate those earlier overrides. Consider either lowering the .esri-widget selector specificity (e.g., avoid :not(...) in the main rule) or adding later, equally/more-specific overrides for .esri-widget.esri-feature-templates and .esri-widget.esri-feature-form so the intended backgrounds still win.

Suggested change
.esri-widget.esri-feature-templates {
background: unset;
}
.esri-widget.esri-feature-form {
background-color: var(--background-grey-1);
}

Copilot uses AI. Check for mistakes.
Comment on lines +92 to +126
<style>
.legend-layout {
display: flex;
flex-direction: column;
gap: 1rem;
}

.legend-controls {
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1.5rem;
}

@@media (min-width: 900px) {
.legend-layout {
flex-direction: row-reverse;
align-items: center;
}

.legend-controls {
flex-direction: column;
flex-wrap: nowrap;
min-width: 220px;
justify-content: center;
}

.legend-map {
flex: 1;
min-height: 500px;
height: 70vh;
max-height: none;
}
}
</style>

Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page embeds a large <style> block directly in the Razor file, but the rest of the sample app typically uses scoped *.razor.css files for per-page styling (e.g., Basemaps.razor.css, FeatureLayers.razor.css). Consider moving these styles into Legends.razor.css to keep styling consistent and easier to maintain.

Suggested change
<style>
.legend-layout {
display: flex;
flex-direction: column;
gap: 1rem;
}
.legend-controls {
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1.5rem;
}
@@media (min-width: 900px) {
.legend-layout {
flex-direction: row-reverse;
align-items: center;
}
.legend-controls {
flex-direction: column;
flex-wrap: nowrap;
min-width: 220px;
justify-content: center;
}
.legend-map {
flex: 1;
min-height: 500px;
height: 70vh;
max-height: none;
}
}
</style>

Copilot uses AI. Check for mistakes.
Comment on lines +69 to +111
<style>
.geojson-layout {
display: flex;
flex-direction: column;
gap: 1rem;
}

.geojson-controls {
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1.5rem;
align-items: center;
}

.geojson-info {
opacity: 0.6;
}

@@media (min-width: 900px) {
.geojson-layout {
flex-direction: row-reverse;
align-items: center;
}

.geojson-controls {
flex-direction: column;
flex-wrap: nowrap;
}

.geojson-controls .form-group {
width: 100%;
box-sizing: border-box;
}

.geojson-map {
flex: 1;
min-height: 500px;
height: 70vh;
max-height: none;
}
}
</style>

Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This page embeds a large <style> block directly in the Razor file, while most other pages use scoped *.razor.css files for page-specific styling. Consider moving these styles into GeoJSONLayers.razor.css for consistency and to avoid mixing layout/CSS into the component markup.

Suggested change
<style>
.geojson-layout {
display: flex;
flex-direction: column;
gap: 1rem;
}
.geojson-controls {
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1.5rem;
align-items: center;
}
.geojson-info {
opacity: 0.6;
}
@@media (min-width: 900px) {
.geojson-layout {
flex-direction: row-reverse;
align-items: center;
}
.geojson-controls {
flex-direction: column;
flex-wrap: nowrap;
}
.geojson-controls .form-group {
width: 100%;
box-sizing: border-box;
}
.geojson-map {
flex: 1;
min-height: 500px;
height: 70vh;
max-height: none;
}
}
</style>

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +8
<a class="btn btn-secondary" target="_blank" href="https://developers.arcgis.com/javascript/latest/sample-code/legend/">ArcGIS Sample</a>
<a class="btn btn-primary" target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Legend.html">Legend API Reference</a>
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These links open in a new tab (target="_blank") but don’t include rel="noopener noreferrer", which leaves the app open to reverse-tabnabbing. Add rel="noopener noreferrer" to external links that use target="_blank".

Suggested change
<a class="btn btn-secondary" target="_blank" href="https://developers.arcgis.com/javascript/latest/sample-code/legend/">ArcGIS Sample</a>
<a class="btn btn-primary" target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Legend.html">Legend API Reference</a>
<a class="btn btn-secondary" target="_blank" rel="noopener noreferrer" href="https://developers.arcgis.com/javascript/latest/sample-code/legend/">ArcGIS Sample</a>
<a class="btn btn-primary" target="_blank" rel="noopener noreferrer" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Legend.html">Legend API Reference</a>

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +8
<a class="btn btn-secondary" target="_blank" href="https://developers.arcgis.com/javascript/latest/sample-code/layers-geojson/">ArcGIS Sample</a>
<a class="btn btn-primary" target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-GeoJSONLayer.html">GeoJSONLayer API Reference</a>
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These links open in a new tab (target="_blank") but don’t include rel="noopener noreferrer", which leaves the app open to reverse-tabnabbing. Add rel="noopener noreferrer" to external links that use target="_blank".

Suggested change
<a class="btn btn-secondary" target="_blank" href="https://developers.arcgis.com/javascript/latest/sample-code/layers-geojson/">ArcGIS Sample</a>
<a class="btn btn-primary" target="_blank" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-GeoJSONLayer.html">GeoJSONLayer API Reference</a>
<a class="btn btn-secondary" target="_blank" rel="noopener noreferrer" href="https://developers.arcgis.com/javascript/latest/sample-code/layers-geojson/">ArcGIS Sample</a>
<a class="btn btn-primary" target="_blank" rel="noopener noreferrer" href="https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-GeoJSONLayer.html">GeoJSONLayer API Reference</a>

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

Code Review — PR #12: Legend & GeoJSON Samples

Overview

Adds two new Core sample pages (Legend, GeoJSON Layers), fixes dark-mode .esri-widget contrast, and fixes the existing UniqueValueRenderers build break. Nicely scoped.

🟡 Concerns

  1. .esri-widget CSS change is global and affects every sample. Replacing color: unset with color: var(--text-emphasis); background-color: var(--background-grey-2); touches every sample that uses any Esri widget. Please sanity-check light mode on the heavy-widget pages (Widgets, Popups, Layer Lists, Search) — there's a real risk of regressed contrast where widgets previously inherited a white/transparent background from the Esri theme CSS. A screenshot of one light-mode page would help reviewers confirm.

  2. USGS time field renders as a Unix millis integer in the popup.

    <PopupTemplate StringContent="... <b>Time:</b> {time}" />

    time is milliseconds since epoch — users will see a 13-digit number. Either switch to FieldInfos with a DateFormat, or use a computed expression. Minor but confusing in a demo.

  3. Checkbox bindings should use @bind, not @onchange toggles.

    <input type="checkbox" @onchange="@(() => _showEarthquakes = !_showEarthquakes)">

    If the DOM and the bound value ever get out of sync (rapid toggling, re-render during a pending event), the checkbox UI and the layer visibility will diverge. @bind="_showEarthquakes" is the idiomatic Blazor pattern and avoids the whole class of issue.

  4. @ref="_censusLayer" is unused in Legends.razor — dead reference, drop it.

  5. @key="_dataUrl" on GeoJSONLayer forces full layer disposal + re-creation on every source switch. For GeoJSON layers that's fine (there's no cheaper way to swap the URL today), but worth a short comment so readers understand why it's there.

🟢 Nice

  • Clear, self-contained pages with links to both the ArcGIS sample and the API reference
  • Media-query responsive layout
  • Good use of SizeVariable on the earthquake renderer

Merge ordering

This PR conflicts with #13 and #14 on UniqueValueRenderers.razor.cs and NavMenu.razor.cs (both contain the same ToUpperFirstChar fix; #13/#14 also modify NavMenu.razor.cs). Whichever merges first will force rebases on the others — suggest merging #12 first (smallest surface area, independent improvement), then #14 (new widget pages), then #13 (nav restructuring that categorizes everything including the pages added by #12/#14).


Generated by Claude Code

- Remove obsolete SourceNav.razor.css (navigation styling)
- Add build-scripts/ directory with cross-platform C# file-based apps:
  - BuildAppSettings.cs: Generate appsettings.json with API/license keys
  - ConsoleDialog.cs: Build progress display window (Windows/macOS/Linux)
  - FetchNuGetVersion.cs: Query latest package version from NuGet.org
  - ScriptBuilder.cs: Compile C# scripts to DLLs for faster execution
- Add MSBuild override files (Directory.Build.props/targets) for isolated script building
- Configure .NET 10 SDK with rollForward: latestMinor via global.json
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants