using System; using System.Globalization; using System.Text; using Avalonia.Controls; using Avalonia.Media; using MiniMvvm; namespace ControlCatalog.Models; public class PageItem(string header, Func factory, StreamGeometry iconData, string description, HomeSection? section) : ViewModelBase { public string Header { get; } = header; public StreamGeometry? IconData { get; } = iconData; public string? Description { get; } = description; public string Section { get; } = section?.Title ?? ""; private string SearchKey { get; } = CreateSearchKey(header, section?.Title ?? ""); public bool IsVisible { get; set { RaiseAndSetIfChanged(ref field, value); section?.RaiseSectionVisibilityChanged(); } } = true; public Page CreatePage() => factory(); public bool MatchesSearch(string searchKey) { return SearchKey.Contains(searchKey, StringComparison.Ordinal); } public static string CreateSearchKey(params ReadOnlySpan values) { var builder = new StringBuilder(256); foreach (var value in values) { var normalizedValue = value.Normalize(NormalizationForm.FormKD); foreach (var c in normalizedValue) { var category = CharUnicodeInfo.GetUnicodeCategory(c); if (category is UnicodeCategory.NonSpacingMark or UnicodeCategory.SpacingCombiningMark or UnicodeCategory.EnclosingMark) { continue; } if (char.IsLetterOrDigit(c)) { builder.Append(char.ToUpperInvariant(c)); } } } return builder.ToString(); } }