{
  "name": "SparkCard",
  "category": "Dashboard",
  "subcategory": null,
  "description": "Small dashboard card with an inline sparkline chart.",
  "thumbnail": "/preview-cards/spark-card.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/SparkCard/SparkCard.razor"
  ],
  "dependencies": [],
  "packageDependencies": [],
  "cssVars": [
    "--color-border",
    "--color-card",
    "--color-card-foreground",
    "--color-foreground",
    "--color-muted",
    "--color-muted-foreground",
    "--radius"
  ],
  "api": {
    "name": "SparkCard",
    "category": "Dashboard",
    "subcategory": null,
    "description": "Small dashboard card with an inline sparkline chart.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/SparkCard/SparkCard.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "Label",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Value",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Data",
        "type": "IEnumerable<double>?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "ChildContent",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Size",
        "type": "SparkCardSize",
        "default": "SparkCardSize.Medium",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Variant",
        "type": "SparkCardVariant",
        "default": "SparkCardVariant.Default",
        "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": [
      {
        "name": "SparkCardSize",
        "values": [
          "Small",
          "Medium",
          "Large"
        ],
        "description": null
      },
      {
        "name": "SparkCardVariant",
        "values": [
          "Default",
          "Bordered",
          "Filled"
        ],
        "description": "Default = standard card border. Bordered = thicker 2px border. Filled = muted background."
      }
    ],
    "records": [],
    "cssVars": [
      "--color-border",
      "--color-card",
      "--color-card-foreground",
      "--color-foreground",
      "--color-muted",
      "--color-muted-foreground",
      "--radius"
    ],
    "examples": [
      {
        "title": "Basic",
        "code": "<Grid Columns=\"3\" Gap=\"4\">\n    <SparkCard Label=\"Revenue\" Value=\"$24,800\" Data=\"@_revenueData\" />\n    <SparkCard Label=\"Sessions\" Value=\"8,412\" Data=\"@_sessionsData\" />\n    <SparkCard Label=\"Bounce Rate\" Value=\"34.2%\" Data=\"@_bounceData\" />\n</Grid>\n\n@code {\n    private IEnumerable<double> _revenueData = new double[] { 12, 18, 14, 22, 19, 25, 21, 30, 28, 35, 31 };\n}"
      },
      {
        "title": "Custom Sparkline Slot",
        "code": "<SparkCard Label=\"Page Views\" Value=\"94,210\">\n    <Sparkline Data=\"@_data\" Class=\"h-10 w-full\" Color=\"var(--color-primary)\" />\n</SparkCard>"
      },
      {
        "title": "Without Data (Label + Value only)",
        "code": "<SparkCard Label=\"Uptime\" Value=\"99.98%\" />\n<SparkCard Label=\"SLA\" Value=\"100%\" />\n<SparkCard Label=\"Incidents\" Value=\"0\" />"
      },
      {
        "title": "Variant (interactive)",
        "code": "<Segmented @bind-Value=\"_variant\">\n    <SegmentedItem Value=\"@SparkCard.SparkCardVariant.Default\">Default</SegmentedItem>\n    <SegmentedItem Value=\"@SparkCard.SparkCardVariant.Bordered\">Bordered</SegmentedItem>\n    <SegmentedItem Value=\"@SparkCard.SparkCardVariant.Filled\">Filled</SegmentedItem>\n</Segmented>\n<Grid Columns=\"3\" Gap=\"4\">\n    <SparkCard Label=\"Revenue\" Value=\"$24,800\" Data=\"@_data\" Variant=\"@_variant\" />\n    <SparkCard Label=\"Sessions\" Value=\"8,412\" Data=\"@_data\" Variant=\"@_variant\" />\n    <SparkCard Label=\"Bounce Rate\" Value=\"34.2%\" Data=\"@_data\" Variant=\"@_variant\" />\n</Grid>\n\n@code { private SparkCard.SparkCardVariant _variant = SparkCard.SparkCardVariant.Default; }"
      }
    ],
    "subComponents": {},
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "spark-card",
  "docsUrl": "https://lumeo.nativ.sh/components/spark-card",
  "sourceUrl": [
    {
      "file": "UI/SparkCard/SparkCard.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/SparkCard/SparkCard.razor"
    }
  ],
  "source": [
    {
      "path": "UI/SparkCard/SparkCard.razor",
      "content": "@namespace Lumeo\n\n<div class=\"@RootClasses\" @attributes=\"AdditionalAttributes\">\n    <div class=\"flex items-baseline justify-between gap-3\">\n        <div class=\"min-w-0\">\n            @if (!string.IsNullOrEmpty(Label))\n            {\n                <div class=\"@LabelClass\">@Label</div>\n            }\n            @if (!string.IsNullOrEmpty(Value))\n            {\n                <div class=\"@ValueClass\">@Value</div>\n            }\n        </div>\n    </div>\n\n    <div class=\"@SparklineHeightClass w-full\">\n        @if (ChildContent is not null)\n        {\n            @ChildContent\n        }\n        else if (Data is not null && _points is not null)\n        {\n            <svg viewBox=\"0 0 100 30\" preserveAspectRatio=\"none\" class=\"h-full w-full overflow-visible\" aria-hidden=\"true\">\n                <polyline points=\"@_points\"\n                          fill=\"none\"\n                          stroke=\"var(--color-primary, currentColor)\"\n                          stroke-width=\"1.5\"\n                          stroke-linecap=\"round\"\n                          stroke-linejoin=\"round\"\n                          vector-effect=\"non-scaling-stroke\" />\n            </svg>\n        }\n    </div>\n</div>\n\n@code {\n    [Parameter] public string? Label { get; set; }\n    [Parameter] public string? Value { get; set; }\n    [Parameter] public IEnumerable<double>? Data { get; set; }\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public SparkCardSize Size { get; set; } = SparkCardSize.Medium;\n    [Parameter] public SparkCardVariant Variant { get; set; } = SparkCardVariant.Default;\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string? _points;\n\n    protected override void OnParametersSet()\n    {\n        _points = ComputePoints(Data);\n    }\n\n    private static string? ComputePoints(IEnumerable<double>? data)\n    {\n        if (data is null) return null;\n        var list = data.ToList();\n        if (list.Count < 2) return null;\n\n        var min = list.Min();\n        var max = list.Max();\n        var range = max - min;\n        if (range == 0) range = 1;\n\n        var sb = new System.Text.StringBuilder();\n        var n = list.Count;\n        for (int i = 0; i < n; i++)\n        {\n            var x = (double)i / (n - 1) * 100.0;\n            // Invert Y so higher values are visually higher (SVG y goes down)\n            var yNorm = (list[i] - min) / range;\n            var y = 28.0 - yNorm * 26.0 + 1.0; // padding 1 top/bottom, area height 26\n            if (i > 0) sb.Append(' ');\n            sb.Append(x.ToString(\"0.##\", System.Globalization.CultureInfo.InvariantCulture));\n            sb.Append(',');\n            sb.Append(y.ToString(\"0.##\", System.Globalization.CultureInfo.InvariantCulture));\n        }\n        return sb.ToString();\n    }\n\n    private string SizePadding => Size switch\n    {\n        SparkCardSize.Small => \"p-3\",\n        SparkCardSize.Large => \"p-6\",\n        _ => \"p-5\"\n    };\n\n    private string SparklineHeightClass => Size switch\n    {\n        SparkCardSize.Small => \"mt-2 h-8\",\n        SparkCardSize.Large => \"mt-4 h-14\",\n        _ => \"mt-3 h-10\"\n    };\n\n    private string LabelClass => Size switch\n    {\n        SparkCardSize.Small => \"text-xs text-muted-foreground truncate\",\n        SparkCardSize.Large => \"text-base text-muted-foreground truncate\",\n        _ => \"text-sm text-muted-foreground truncate\"\n    };\n\n    private string ValueClass => Size switch\n    {\n        SparkCardSize.Small => \"mt-0.5 text-lg font-semibold tracking-tight text-foreground\",\n        SparkCardSize.Large => \"mt-1.5 text-3xl font-semibold tracking-tight text-foreground\",\n        _ => \"mt-1 text-2xl font-semibold tracking-tight text-foreground\"\n    };\n\n    private string VariantClasses => Variant switch\n    {\n        SparkCardVariant.Bordered => \"rounded-xl border-2 border-border bg-card text-card-foreground\",\n        SparkCardVariant.Filled => \"rounded-xl border border-border/40 bg-muted text-card-foreground\",\n        _ => \"rounded-xl border border-border bg-card text-card-foreground\"\n    };\n\n    private string RootClasses =>\n        $\"{VariantClasses} {SizePadding} {Class}\".Trim();\n\n    public enum SparkCardSize { Small, Medium, Large }\n    /// <summary>\n    /// Default = standard card border. Bordered = thicker 2px border. Filled = muted background.\n    /// </summary>\n    public enum SparkCardVariant { Default, Bordered, Filled }\n}\n"
    }
  ],
  "slots": [
    {
      "name": "ChildContent",
      "owner": "SparkCard",
      "type": "RenderFragment?",
      "description": null
    }
  ],
  "serviceDependencies": [],
  "cascadingDependencies": [],
  "relatedComponents": [],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Tests/Components/SparkCard/SparkCardTests.cs"
  ],
  "mdSummary": "# SparkCard\n\nSmall dashboard card with an inline sparkline chart.\n\n**Package:** `Lumeo` · **Category:** Dashboard\n**Docs:** https://lumeo.nativ.sh/components/spark-card\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| SparkCard | Label | `string?` | `` |  |\n| SparkCard | Value | `string?` | `` |  |\n| SparkCard | Data | `IEnumerable<double>?` | `` |  |\n| SparkCard | ChildContent | `RenderFragment?` | `` |  |\n| SparkCard | Size | `SparkCardSize` | `SparkCardSize.Medium` |  |\n| SparkCard | Variant | `SparkCardVariant` | `SparkCardVariant.Default` |  |\n| SparkCard | Class | `string?` | `` |  |\n| SparkCard | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- `ChildContent` (SparkCard) — RenderFragment slot\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<SparkCard />\n```\n\n## CSS variables\n`--color-border`, `--color-card`, `--color-card-foreground`, `--color-foreground`, `--color-muted`, `--color-muted-foreground`, `--radius`\n\n## Files\n- `UI/SparkCard/SparkCard.razor`\n"
}