Class Sealed
public sealed class MokaJsonBreadcrumb : ComponentBase

Namespace: Moka.Blazor.Json.Components

Displays the JSON Pointer path as a clickable breadcrumb trail.

Inheritance

Inherits from: ComponentBase

Properties

NameDescription
OnNavigate Callback when a breadcrumb segment is clicked.
Path The currently selected JSON Pointer path.
RootValueKind The root element's value kind for type icon display.

OnNavigate

EventCallback<string> MokaJsonBreadcrumb.OnNavigate { get; set; }

Callback when a breadcrumb segment is clicked.

Path

string? MokaJsonBreadcrumb.Path { get; set; }

The currently selected JSON Pointer path.

RootValueKind

JsonValueKind MokaJsonBreadcrumb.RootValueKind { get; set; }

The root element's value kind for type icon display.

Type Relationships
classDiagram
                    style MokaJsonBreadcrumb fill:#f9f,stroke:#333,stroke-width:2px
                    MokaJsonBreadcrumb --|> ComponentBase : inherits
                
View Source
/// <summary>
///     Displays the JSON Pointer path as a clickable breadcrumb trail.
/// </summary>
public sealed partial class MokaJsonBreadcrumb : ComponentBase
{
#region Nested Types
    private sealed class BreadcrumbSegment
    {
        public required string Label { get; init; }
        public required string DisplayLabel { get; init; }
        public required string Path { get; init; }
        public string? TypeIcon { get; init; }
    }

#endregion
#region Private Methods
    private Task HandleRootClick() => OnNavigate.InvokeAsync(string.Empty);
    private static bool NeedsQuoting(string propertyName)
    {
        if (propertyName.Length == 0)
        {
            return true;
        }

        foreach (char c in propertyName)
        {
            if (c is '.' or ' ' or '[' or ']' or '"' or '\'' or '/')
            {
                return true;
            }
        }

        return false;
    }

#endregion
#region Parameters
    /// <summary>The currently selected JSON Pointer path.</summary>
    [Parameter]
    public string? Path { get; set; }

    /// <summary>The root element's value kind for type icon display.</summary>
    [Parameter]
    public JsonValueKind RootValueKind { get; set; }

    /// <summary>Callback when a breadcrumb segment is clicked.</summary>
    [Parameter]
    public EventCallback<string> OnNavigate { get; set; }

#endregion
#region State Fields
    private string? _cachedPath;
    private List<BreadcrumbSegment> _cachedSegments = [];
#endregion
#region Computed Properties
    private string RootTypeIcon => RootValueKind switch
    {
        JsonValueKind.Object => "{}",
        JsonValueKind.Array => "[]",
        _ => ""
    };

    private List<BreadcrumbSegment> Segments
    {
        get
        {
            if (Path == _cachedPath)
            {
                return _cachedSegments;
            }

            _cachedPath = Path;
            if (string.IsNullOrEmpty(Path))
            {
                _cachedSegments = [];
                return _cachedSegments;
            }

            string[] parts = Path.Split('/', StringSplitOptions.RemoveEmptyEntries);
            var segments = new List<BreadcrumbSegment>(parts.Length);
            var sb = new StringBuilder(Path.Length);
            foreach (string part in parts)
            {
                string unescaped = JsonPointerHelper.UnescapeSegment(part);
                sb.Append('/');
                sb.Append(part);
                string displayLabel;
                if (int.TryParse(unescaped, out int index))
                {
                    displayLabel = $"[{index}]";
                }
                else if (NeedsQuoting(unescaped))
                {
                    displayLabel = $"[\"{unescaped}\"]";
                }
                else
                {
                    displayLabel = unescaped;
                }

                segments.Add(new BreadcrumbSegment { Label = unescaped, DisplayLabel = displayLabel, Path = sb.ToString(), TypeIcon = null });
            }

            _cachedSegments = segments;
            return _cachedSegments;
        }
    }
#endregion
}
Was this page helpful?