{
  "name": "Highlighter",
  "category": "Typography",
  "subcategory": null,
  "description": "Wraps occurrences of one or more search terms in the text with highlight marks.",
  "thumbnail": "/preview-cards/highlighter.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/Highlighter/Highlighter.razor"
  ],
  "dependencies": [],
  "packageDependencies": [],
  "cssVars": [
    "--color-foreground",
    "--radius"
  ],
  "api": {
    "name": "Highlighter",
    "category": "Typography",
    "subcategory": null,
    "description": "Wraps occurrences of one or more search terms in the text with highlight marks.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/Highlighter/Highlighter.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "Text",
        "type": "string",
        "default": "\"\"",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Highlight",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "HighlightTerms",
        "type": "IEnumerable<string>?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "CaseSensitive",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "WholeWord",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "HighlightClass",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Tag",
        "type": "string",
        "default": "\"mark\"",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Class",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "AdditionalAttributes",
        "type": "Dictionary<string, object>?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": true
      }
    ],
    "events": [],
    "enums": [],
    "records": [
      {
        "name": "Segment",
        "signature": "Segment(string Text, bool IsMatch)",
        "description": null
      }
    ],
    "cssVars": [
      "--color-foreground",
      "--radius"
    ],
    "examples": [
      {
        "title": "Single Term",
        "code": "<Highlighter Text=\"The quick brown fox jumps over the lazy dog\" Highlight=\"fox\" />"
      },
      {
        "title": "Case Sensitive",
        "code": "<!-- Case insensitive (default) -->\n<Highlighter Text=\"Blazor is awesome. blazor runs on .NET.\" Highlight=\"blazor\" />\n\n<!-- Case sensitive -->\n<Highlighter Text=\"Blazor is awesome. blazor runs on .NET.\" Highlight=\"Blazor\" CaseSensitive=\"true\" />"
      },
      {
        "title": "Whole Word",
        "code": "<!-- Partial matches -->\n<Highlighter Text=\"highlight highlighting highlighted\" Highlight=\"highlight\" />\n\n<!-- Whole word only -->\n<Highlighter Text=\"highlight highlighting highlighted\" Highlight=\"highlight\" WholeWord=\"true\" />"
      },
      {
        "title": "Interactive Search",
        "code": "<Input Placeholder=\"Type to search...\" @bind-Value=\"_searchTerm\" />\n<Highlighter Text=\"@sampleText\" Highlight=\"@_searchTerm\" />"
      }
    ],
    "subComponents": {},
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "highlighter",
  "docsUrl": "https://lumeo.nativ.sh/components/highlighter",
  "sourceUrl": [
    {
      "file": "UI/Highlighter/Highlighter.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Highlighter/Highlighter.razor"
    }
  ],
  "source": [
    {
      "path": "UI/Highlighter/Highlighter.razor",
      "content": "@namespace Lumeo\n\n<span class=\"@ContainerClass\" @attributes=\"AdditionalAttributes\">\n    @foreach (var segment in _segments)\n    {\n        if (segment.IsMatch)\n        {\n            <mark class=\"@MarkClass\">@segment.Text</mark>\n        }\n        else\n        {\n            @segment.Text\n        }\n    }\n</span>\n\n@code {\n    [Parameter] public string Text { get; set; } = \"\";\n    [Parameter] public string? Highlight { get; set; }\n    [Parameter] public IEnumerable<string>? HighlightTerms { get; set; }\n    [Parameter] public bool CaseSensitive { get; set; }\n    [Parameter] public bool WholeWord { get; set; }\n    [Parameter] public string? HighlightClass { get; set; }\n    [Parameter] public string Tag { get; set; } = \"mark\";\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private List<Segment> _segments = new();\n\n    private string ContainerClass => $\"{Class}\".Trim();\n\n    private string MarkClass =>\n        ($\"bg-warning/30 text-foreground rounded-sm px-0.5 {HighlightClass}\").Trim();\n\n    protected override void OnParametersSet() => Rebuild();\n\n    private void Rebuild()\n    {\n        _segments.Clear();\n\n        if (string.IsNullOrEmpty(Text))\n            return;\n\n        // Collect terms, largest first to ensure longest match wins\n        var terms = new List<string>();\n        if (!string.IsNullOrEmpty(Highlight))\n            terms.Add(Highlight);\n        if (HighlightTerms is not null)\n            terms.AddRange(HighlightTerms.Where(t => !string.IsNullOrEmpty(t)));\n\n        // De-duplicate\n        terms = terms.Distinct(\n            CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase\n        ).OrderByDescending(t => t.Length).ToList();\n\n        if (terms.Count == 0)\n        {\n            _segments.Add(new Segment(Text, false));\n            return;\n        }\n\n        // Build a combined regex: alternate longest-first\n        var escaped = terms.Select(t =>\n        {\n            var e = System.Text.RegularExpressions.Regex.Escape(t);\n            return WholeWord ? $@\"\\b{e}\\b\" : e;\n        });\n        var pattern = string.Join(\"|\", escaped);\n        var options = System.Text.RegularExpressions.RegexOptions.None;\n        if (!CaseSensitive)\n            options |= System.Text.RegularExpressions.RegexOptions.IgnoreCase;\n\n        System.Text.RegularExpressions.Regex? regex = null;\n        try\n        {\n            regex = new System.Text.RegularExpressions.Regex(pattern, options);\n        }\n        catch\n        {\n            // Bad pattern — render plain\n            _segments.Add(new Segment(Text, false));\n            return;\n        }\n\n        int pos = 0;\n        foreach (System.Text.RegularExpressions.Match m in regex.Matches(Text))\n        {\n            if (m.Index > pos)\n                _segments.Add(new Segment(Text[pos..m.Index], false));\n            _segments.Add(new Segment(m.Value, true));\n            pos = m.Index + m.Length;\n        }\n\n        if (pos < Text.Length)\n            _segments.Add(new Segment(Text[pos..], false));\n    }\n\n    private record Segment(string Text, bool IsMatch);\n}\n"
    }
  ],
  "slots": [],
  "serviceDependencies": [],
  "cascadingDependencies": [],
  "relatedComponents": [],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Tests/Components/Highlighter/HighlighterTests.cs"
  ],
  "mdSummary": "# Highlighter\n\nWraps occurrences of one or more search terms in the text with highlight marks.\n\n**Package:** `Lumeo` · **Category:** Typography\n**Docs:** https://lumeo.nativ.sh/components/highlighter\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| Highlighter | Text | `string` | `\"\"` |  |\n| Highlighter | Highlight | `string?` | `` |  |\n| Highlighter | HighlightTerms | `IEnumerable<string>?` | `` |  |\n| Highlighter | CaseSensitive | `bool` | `` |  |\n| Highlighter | WholeWord | `bool` | `` |  |\n| Highlighter | HighlightClass | `string?` | `` |  |\n| Highlighter | Tag | `string` | `\"mark\"` |  |\n| Highlighter | Class | `string?` | `` |  |\n| Highlighter | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- (none)\n\n## Events\n- (none)\n\n## Sub-components\n- (none)\n\n## Cascading values it expects\n- (none)\n\n## Services it injects\n- (none)\n\n## Keyboard\n—\n\n## Example\n```razor\n<Highlighter />\n```\n\n## CSS variables\n`--color-foreground`, `--radius`\n\n## Files\n- `UI/Highlighter/Highlighter.razor`\n"
}