Conversation
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>
There was a problem hiding this comment.
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.cswith 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); | ||
| } | ||
|
|
There was a problem hiding this comment.
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.
| .esri-widget.esri-feature-templates { | |
| background: unset; | |
| } | |
| .esri-widget.esri-feature-form { | |
| background-color: var(--background-grey-1); | |
| } |
| }; | ||
| 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)) |
There was a problem hiding this comment.
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.
| .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)) |
| <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> | ||
|
|
There was a problem hiding this comment.
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.
| <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> |
| <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> | ||
|
|
There was a problem hiding this comment.
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.
| <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> |
| <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> |
There was a problem hiding this comment.
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".
| <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> |
| <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> |
There was a problem hiding this comment.
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".
| <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> |
Summary
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
unset, fixing white widget backgrounds and unreadable text in dark mode across all samples.
Bug Fix
manipulation.