Skip to content

Add Legend and GeoJSON samples#12

Open
magmoe wants to merge 1 commit intomainfrom
feature/11-new-samples-and-styling
Open

Add Legend and GeoJSON samples#12
magmoe wants to merge 1 commit 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.
};
private readonly UniqueValueRenderer _uniqueValueRenderer = new(uniqueValueInfos: roadTypes
.Select(r => new UniqueValueInfo(r.Key.ToUpperFirstChar().Replace("_", " "), r.Value, r.Key))
.Select(r => new UniqueValueInfo(string.Concat(r.Key[0].ToString().ToUpper(), r.Key.AsSpan(1)).Replace("_", " "), r.Value, r.Key))
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 capitalization uses ToUpper() which is culture-sensitive and can produce unexpected results under some cultures (e.g., Turkish). Use an invariant casing operation (e.g., ToUpperInvariant() / char.ToUpperInvariant) to keep labels stable regardless of the current culture.

Suggested change
.Select(r => new UniqueValueInfo(string.Concat(r.Key[0].ToString().ToUpper(), r.Key.AsSpan(1)).Replace("_", " "), r.Value, r.Key))
.Select(r => new UniqueValueInfo(string.Concat(r.Key[0].ToString().ToUpperInvariant(), r.Key.AsSpan(1)).Replace("_", " "), r.Value, r.Key))

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.
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.

2 participants