Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,56 @@
<SearchBox Filter="OnSearchFilter" FullSearch="OnFullSearch" />
<div id="lower-nav-container" @ref="Navbar" class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav-list">
@foreach (PageLink page in FilteredPages)
@foreach (PageLink page in UngroupedPages)
{
string linkClass = $"nav-list-link{(page.Pro ? " pro" : "")}";
<li class="nav-list-item" @onclick="@(() => NavigateTo(page.Href))">
<NavLink class="@linkClass" href="@(page.Href)" @onclick:preventDefault="true" Match="NavLinkMatch.All">
@if (page.IconClass is not null)
{
<text><span class="oi @(page.IconClass)" aria-hidden="true"></span><span class="nav-item-title">@(page.Title)</span></text>
}
else
<li class="nav-list-item nav-pinned" @onclick="@(() => NavigateTo(page.Href))">
@RenderNavLink(page)
</li>
}

@foreach (var (groupName, pages) in GroupedFilteredPages)
{
bool expanded = IsGroupExpanded(groupName);
<li class="nav-list-item nav-group @(expanded ? "active" : "")">
<button type="button" class="nav-list-expander" aria-expanded="@expanded" @onclick="@(() => ToggleGroup(groupName))" @onclick:stopPropagation="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
<path d="M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06Z" />
</svg>
<span class="nav-group-title">@groupName</span>
</button>
@if (expanded)
{
<ul class="nav-list nav-sublist">
@foreach (PageLink page in pages)
{
<text><span class="oi"><img src="_content/dymaptic.GeoBlazor.Core.Sample.Shared/images/@(page.ImageFile)" alt="@(page.Title)" /></span><span class="nav-item-title">@(page.Title)</span></text>
<li class="nav-list-item" @onclick="@(() => NavigateTo(page.Href))">
@RenderNavLink(page)
</li>
}
</NavLink>
</ul>
}
</li>
}
</ul>
</div>
</nav>
</nav>

@code {
RenderFragment RenderNavLink(PageLink page)
{
string linkClass = $"nav-list-link{(page.Pro ? " pro" : "")}";
return @<NavLink class="@linkClass" href="@(page.Href)" @onclick:preventDefault="true" Match="NavLinkMatch.All">
@if (page.IconClass is not null)
{
<text><span class="oi @(page.IconClass)" aria-hidden="true"></span><span
class="nav-item-title">@(page.Title)</span></text>
}
else
{
<text><span class="oi"><img src="_content/dymaptic.GeoBlazor.Core.Sample.Shared/images/@(page.ImageFile)"
alt="@(page.Title)"/></span><span
class="nav-item-title">@(page.Title)</span></text>
}
</NavLink>;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ namespace dymaptic.GeoBlazor.Core.Sample.Shared.Shared;

public partial class NavMenu
{
// Category name constants
public static class Categories
{
public const string MapsAndScenes = "Maps & Scenes";
public const string Layers = "Layers";
public const string Visualization = "Visualization";
public const string Widgets = "Widgets";
public const string Queries = "Queries";
public const string Interaction = "Interaction";
public const string Location = "Location";
}

protected static readonly string[] GroupOrder =
[Categories.MapsAndScenes, Categories.Layers, Categories.Visualization,
Categories.Widgets, Categories.Queries, Categories.Interaction, Categories.Location];

[Inject]
public required IJSRuntime JsRuntime { get; set; }
[Inject]
Expand All @@ -20,6 +36,31 @@ public partial class NavMenu
? Pages
: Pages.Where(p => p.Title.Contains(_searchText, StringComparison.OrdinalIgnoreCase));

protected IEnumerable<PageLink> UngroupedPages => FilteredPages.Where(p => p.Category is null);

protected IEnumerable<(string GroupName, IEnumerable<PageLink> Pages)> GroupedFilteredPages =>
GroupOrder
.Select(g => (GroupName: g, Pages: FilteredPages.Where(p => p.Category == g)))
.Where(g => g.Pages.Any());

protected HashSet<string> ExpandedGroups { get; set; } = new();

protected void ToggleGroup(string groupName)
{
if (!ExpandedGroups.Add(groupName))
{
ExpandedGroups.Remove(groupName);
}
}

protected bool IsGroupExpanded(string groupName)
{
if (!string.IsNullOrWhiteSpace(_searchText))
return true;

return ExpandedGroups.Contains(groupName);
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
Expand All @@ -37,9 +78,16 @@ protected override async Task OnAfterRenderAsync(bool firstRender)

if (currentPage != string.Empty)
{
string? group = Pages.FirstOrDefault(p => p.Href == currentPage)?.Category;

if (group is not null)
{
ExpandedGroups.Add(group);
}

await JsRuntime.InvokeVoidAsync("scrollToNav", currentPage);
}

StateHasChanged();
}
}
Expand Down Expand Up @@ -96,58 +144,67 @@ await InvokeAsync(async () =>
public virtual PageLink[] Pages =>
[
new("", "Home", "oi-home"),
new("navigation", "Navigation", "oi-compass"),
new("drawing", "Drawing", "oi-pencil"),
new("click-to-add", "Click to Add Point", "oi-map-marker"),
new("many-graphics", "Many Graphics", "oi-calculator"),
new("scene", "Scene & Attributes", "oi-globe"),
new("widgets", "Widgets", "oi-location"),
new("basemaps", "Basemaps", "oi-map"),
new("feature-layers", "Feature Layers", "oi-layers"),
new("map-image-layers", "Map Image Layers", "oi-image"),
new("labels", "Labels", "oi-text"),
new("popups", "Popups", "oi-chat"),
new("popup-actions", "Popup Actions", "oi-bullhorn"),
new("bookmarks", "Bookmarks", "oi-bookmark"),
new("vector-layer", "Vector Layer", "oi-arrow-right"),
new("layer-lists", "Layer Lists", "oi-list"),
new("basemap-layer-lists", "Basemap Layer Lists", "oi-spreadsheet"),
new("csv-layer", "CSV Layers", "oi-grid-four-up"),
new("kmllayers", "KML Layers", "oi-excerpt"),
new("geojson-layers", "GeoJSON Layers", null, "geojson.svg"),
new("georss-layer", "GeoRSS Layer", "oi-rss"),
new("osm-layer", "OpenStreetMaps Layer", null, "osm.webp"),
new("wcslayers", "WCS Layers", "oi-project"),
new("wfslayers", "WFS Layers", null, "wfs.svg"),
new("wmslayers", "WMS Layers", null, "wms.svg"),
new("wmtslayers", "WMTS Layers", null, "wmts.svg"),
new("imagerylayer", "Imagery Layers", "oi-image"),
new("imagery-tile-layer", "Imagery Tile Layers", null, "tile.webp"),
new("web-map", "Web Map", "oi-browser"),
new("web-scene", "Web Scene", "oi-box"),
new("events", "Events", "oi-flash"),
new("reactive-utils", "Reactive Utils", "oi-wrench"),
new("hit-tests", "Hit Tests", "oi-star"),
new("sql-query", "SQL Query", "oi-data-transfer-download"),
new("sql-filter-query", "SQL Filter", "oi-arrow-thick-bottom"),
new("server-side-queries", "Server-Side Queries", "oi-question-mark"),
new("query-related-features", "Query Related Features", "oi-people"),
new("query-top-features", "Query Top Features", "oi-arrow-thick-top"),
new("place-selector", "Place Selector", "oi-arrow-bottom"),
new("service-areas", "Service Areas", "oi-comment-square"),
new("measurement-widgets", "Measurement Widgets", null, "ruler.svg"),
new("calculate-geometries", "Calculate Geometries", "oi-clipboard"),
new("projection", "Display Projection", "oi-sun"),
new("projection-tool", "Projection Tool", "oi-cog"),
new("basemap-projections", "Basemap Projections", "oi-bullhorn"),
new("legends", "Legend", null, "legend.svg"),
new("unique-value", "Unique Renderers", "oi-eyedropper"),
new("marker-rotation", "Marker Rotation", "oi-loop-circular"),
new("graphic-tracking", "Graphic Tracking", "oi-move"),
new("geometry-methods", "Geometry Methods", "oi-task"),
new("locator-methods", "Locator Methods", "oi-task"),
new("search-multi-source", "Search Multiple Sources", "oi-magnifying-glass"),
new("reverse-geolocator", "GeoLocator", "oi-arrow-circle-bottom")
new("navigation", "Navigation", "oi-compass", Category: Categories.MapsAndScenes),
new("scene", "Scene & Attributes", "oi-globe", Category: Categories.MapsAndScenes),
new("basemaps", "Basemaps", "oi-map", Category: Categories.MapsAndScenes),
new("web-map", "Web Map", "oi-browser", Category: Categories.MapsAndScenes),
new("web-scene", "Web Scene", "oi-box", Category: Categories.MapsAndScenes),

new("feature-layers", "Feature Layers", "oi-layers", Category: Categories.Layers),
new("map-image-layers", "Map Image Layers", "oi-image", Category: Categories.Layers),
new("vector-layer", "Vector Layer", "oi-arrow-right", Category: Categories.Layers),
new("csv-layer", "CSV Layers", "oi-grid-four-up", Category: Categories.Layers),
new("kmllayers", "KML Layers", "oi-excerpt", Category: Categories.Layers),
new("geojson-layers", "GeoJSON Layers", null, "geojson.svg", Category: Categories.Layers),
new("georss-layer", "GeoRSS Layer", "oi-rss", Category: Categories.Layers),
new("osm-layer", "OpenStreetMaps Layer", null, "osm.webp", Category: Categories.Layers),
new("wcslayers", "WCS Layers", "oi-project", Category: Categories.Layers),
new("wfslayers", "WFS Layers", null, "wfs.svg", Category: Categories.Layers),
new("wmslayers", "WMS Layers", null, "wms.svg", Category: Categories.Layers),
new("wmtslayers", "WMTS Layers", null, "wmts.svg", Category: Categories.Layers),
new("imagerylayer", "Imagery Layers", "oi-image", Category: Categories.Layers),
new("imagery-tile-layer", "Imagery Tile Layers", null, "tile.webp", Category: Categories.Layers),

new("labels", "Labels", "oi-text", Category: Categories.Visualization),
new("unique-value", "Unique Renderers", "oi-eyedropper", Category: Categories.Visualization),
new("marker-rotation", "Marker Rotation", "oi-loop-circular", Category: Categories.Visualization),

new("widgets", "Widgets", "oi-location", Category: Categories.Widgets),
new("popups", "Popups", "oi-chat", Category: Categories.Widgets),
new("popup-actions", "Popup Actions", "oi-bullhorn", Category: Categories.Widgets),
new("bookmarks", "Bookmarks", "oi-bookmark", Category: Categories.Widgets),
new("layer-lists", "Layer Lists", "oi-list", Category: Categories.Widgets),
new("legends", "Legend", null, "legend.svg", Category: Categories.Widgets),
new("basemap-layer-lists", "Basemap Layer Lists", "oi-spreadsheet", Category: Categories.Widgets),
new("measurement-widgets", "Measurement Widgets", null, "ruler.svg", Category: Categories.Widgets),
new("search-multi-source", "Search Multiple Sources", "oi-magnifying-glass", Category: Categories.Widgets),

new("sql-query", "SQL Query", "oi-data-transfer-download", Category: Categories.Queries),
new("sql-filter-query", "SQL Filter", "oi-arrow-thick-bottom", Category: Categories.Queries),
new("server-side-queries", "Server-Side Queries", "oi-question-mark", Category: Categories.Queries),
new("query-related-features", "Query Related Features", "oi-people", Category: Categories.Queries),
new("query-top-features", "Query Top Features", "oi-arrow-thick-top", Category: Categories.Queries),

new("drawing", "Drawing", "oi-pencil", Category: Categories.Interaction),
new("click-to-add", "Click to Add Point", "oi-map-marker", Category: Categories.Interaction),
new("many-graphics", "Many Graphics", "oi-calculator", Category: Categories.Interaction),
new("events", "Events", "oi-flash", Category: Categories.Interaction),
new("reactive-utils", "Reactive Utils", "oi-wrench", Category: Categories.Interaction),
new("hit-tests", "Hit Tests", "oi-star", Category: Categories.Interaction),
new("graphic-tracking", "Graphic Tracking", "oi-move", Category: Categories.Interaction),

new("place-selector", "Place Selector", "oi-arrow-bottom", Category: Categories.Location),
new("service-areas", "Service Areas", "oi-comment-square", Category: Categories.Location),
new("calculate-geometries", "Calculate Geometries", "oi-clipboard", Category: Categories.Location),
new("projection", "Display Projection", "oi-sun", Category: Categories.Location),
new("projection-tool", "Projection Tool", "oi-cog", Category: Categories.Location),
new("basemap-projections", "Basemap Projections", "oi-bullhorn", Category: Categories.Location),
new("geometry-methods", "Geometry Methods", "oi-task", Category: Categories.Location),
new("locator-methods", "Locator Methods", "oi-task", Category: Categories.Location),
new("reverse-geolocator", "GeoLocator", "oi-arrow-circle-bottom", Category: Categories.Location),
];
public record PageLink(string Href, string Title, string? IconClass = null, string? ImageFile = null, bool Pro = false);

public record PageLink(
string Href, string Title, string? IconClass = null,
string? ImageFile = null, bool Pro = false, string? Category = null);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

#lower-nav-container {
position: absolute;
top: 9rem;
top: 10rem;
left: 0;
background-color: var(--background-grey-2);
width: 20rem;
overflow-y: auto;
height: calc(100vh - 9rem);
height: calc(100vh - 10rem);
margin: 0;
padding: 1rem 0;
}
Expand All @@ -42,7 +42,7 @@
width: 2rem;
font-size: 1.1rem;
vertical-align: text-top;
top: 2px;
top: -2px;
}

.oi img {
Expand Down
Loading
Loading