{
  "name": "Gauge",
  "category": "Data Display",
  "subcategory": null,
  "description": "Single-value gauge with radial, arc, and linear variants and threshold colour bands.",
  "thumbnail": "/preview-cards/gauge.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/Gauge/Gauge.razor"
  ],
  "dependencies": [],
  "packageDependencies": [],
  "cssVars": [
    "--color-foreground"
  ],
  "api": {
    "name": "Gauge",
    "category": "Data Display",
    "subcategory": null,
    "description": "Single-value gauge with radial, arc, and linear variants and threshold colour bands.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/Gauge/Gauge.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "Value",
        "type": "double",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Min",
        "type": "double",
        "default": "0",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Max",
        "type": "double",
        "default": "100",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Variant",
        "type": "GaugeVariant",
        "default": "GaugeVariant.Radial",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Size",
        "type": "int",
        "default": "120",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "StrokeWidth",
        "type": "int",
        "default": "8",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Label",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "ShowValue",
        "type": "bool",
        "default": "true",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Color",
        "type": "string",
        "default": "\"primary\"",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "TrackColor",
        "type": "string",
        "default": "\"muted\"",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Thresholds",
        "type": "IReadOnlyList<GaugeThreshold>?",
        "default": null,
        "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": "GaugeVariant",
        "values": [
          "Radial",
          "Linear",
          "Arc"
        ],
        "description": null
      }
    ],
    "records": [
      {
        "name": "GaugeThreshold",
        "signature": "GaugeThreshold(double Value, string Color)",
        "description": null
      }
    ],
    "cssVars": [
      "--color-foreground"
    ],
    "examples": [
      {
        "title": "Radial (default)",
        "code": "<Gauge Value=\"25\" />\n<Gauge Value=\"60\" />\n<Gauge Value=\"90\" />"
      },
      {
        "title": "Arc (semicircle)",
        "code": "<Gauge Value=\"30\" Variant=\"Gauge.GaugeVariant.Arc\" />\n<Gauge Value=\"65\" Variant=\"Gauge.GaugeVariant.Arc\" />\n<Gauge Value=\"95\" Variant=\"Gauge.GaugeVariant.Arc\" />"
      },
      {
        "title": "Linear",
        "code": "<Gauge Value=\"40\" Variant=\"Gauge.GaugeVariant.Linear\" Size=\"200\" />\n<Gauge Value=\"70\" Variant=\"Gauge.GaugeVariant.Linear\" Size=\"200\" Color=\"success\" />\n<Gauge Value=\"90\" Variant=\"Gauge.GaugeVariant.Linear\" Size=\"200\" Color=\"destructive\" />"
      },
      {
        "title": "Custom Label",
        "code": "<Gauge Value=\"72\" Label=\"CPU\" Size=\"120\" />\n<Gauge Value=\"48\" Label=\"RAM\" Size=\"120\" />\n<Gauge Value=\"33\" Label=\"Disk\" Size=\"120\" />"
      }
    ],
    "subComponents": {},
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "gauge",
  "docsUrl": "https://lumeo.nativ.sh/components/gauge",
  "sourceUrl": [
    {
      "file": "UI/Gauge/Gauge.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Gauge/Gauge.razor"
    }
  ],
  "source": [
    {
      "path": "UI/Gauge/Gauge.razor",
      "content": "@namespace Lumeo\n\n@if (Variant == GaugeVariant.Linear)\n{\n    <div class=\"@ContainerClass\"\n         role=\"meter\"\n         aria-valuenow=\"@Value.ToString(System.Globalization.CultureInfo.InvariantCulture)\"\n         aria-valuemin=\"@Min.ToString(System.Globalization.CultureInfo.InvariantCulture)\"\n         aria-valuemax=\"@Max.ToString(System.Globalization.CultureInfo.InvariantCulture)\"\n         aria-label=\"@(Label ?? DisplayValue)\"\n         @attributes=\"AdditionalAttributes\">\n        <svg width=\"@Size\" height=\"@StrokeWidth\" viewBox=\"0 0 @Size @StrokeWidth\"\n             xmlns=\"http://www.w3.org/2000/svg\">\n            <rect x=\"0\" y=\"0\" width=\"@Size\" height=\"@StrokeWidth\"\n                  rx=\"@(StrokeWidth / 2)\"\n                  fill=\"var(--color-@TrackColor)\" />\n            <rect x=\"0\" y=\"0\" width=\"@LinearFillWidth\" height=\"@StrokeWidth\"\n                  rx=\"@(StrokeWidth / 2)\"\n                  fill=\"@ActiveColor\"\n                  style=\"transition: width 0.3s ease;\" />\n        </svg>\n        @if (ShowValue)\n        {\n            <span class=\"text-xs text-foreground font-medium mt-1 block text-center\"\n                  style=\"width: @(Size)px\">@DisplayValue</span>\n        }\n    </div>\n}\nelse\n{\n    @* Radial = 270° arc (gap at bottom), Arc = 180° semicircle (top half) *@\n    <div class=\"@ArcContainerClass\"\n         role=\"meter\"\n         aria-valuenow=\"@Value.ToString(System.Globalization.CultureInfo.InvariantCulture)\"\n         aria-valuemin=\"@Min.ToString(System.Globalization.CultureInfo.InvariantCulture)\"\n         aria-valuemax=\"@Max.ToString(System.Globalization.CultureInfo.InvariantCulture)\"\n         aria-label=\"@(Label ?? DisplayValue)\"\n         style=\"@ArcContainerStyle\"\n         @attributes=\"AdditionalAttributes\">\n        <svg width=\"@Size\" height=\"@SvgHeight\"\n             viewBox=\"0 0 @Size @SvgHeight\"\n             xmlns=\"http://www.w3.org/2000/svg\"\n             style=\"overflow: visible; display: block;\">\n            @* Track arc *@\n            <circle cx=\"@CxStr\" cy=\"@CyStr\" r=\"@RadiusStr\"\n                    fill=\"none\"\n                    stroke=\"var(--color-@TrackColor)\"\n                    stroke-width=\"@StrokeWidth\"\n                    stroke-linecap=\"round\"\n                    stroke-dasharray=\"@TrackDash\"\n                    stroke-dashoffset=\"0\"\n                    transform=\"rotate(@StartAngleDeg @CxStr @CyStr)\" />\n            @* Value arc *@\n            <circle cx=\"@CxStr\" cy=\"@CyStr\" r=\"@RadiusStr\"\n                    fill=\"none\"\n                    stroke=\"@ActiveColor\"\n                    stroke-width=\"@StrokeWidth\"\n                    stroke-linecap=\"round\"\n                    stroke-dasharray=\"@ValueDash\"\n                    stroke-dashoffset=\"0\"\n                    transform=\"rotate(@StartAngleDeg @CxStr @CyStr)\"\n                    style=\"transition: stroke-dasharray 0.3s ease;\" />\n        </svg>\n        @if (ShowValue)\n        {\n            <span class=\"absolute inset-0 flex items-center justify-center text-foreground font-medium pointer-events-none\"\n                  style=\"font-size: @(LabelFontSize)px; @LabelOffset\">@DisplayValue</span>\n        }\n    </div>\n}\n\n@code {\n    [Parameter] public double Value { get; set; }\n    [Parameter] public double Min { get; set; } = 0;\n    [Parameter] public double Max { get; set; } = 100;\n    [Parameter] public GaugeVariant Variant { get; set; } = GaugeVariant.Radial;\n    [Parameter] public int Size { get; set; } = 120;\n    [Parameter] public int StrokeWidth { get; set; } = 8;\n    [Parameter] public string? Label { get; set; }\n    [Parameter] public bool ShowValue { get; set; } = true;\n    [Parameter] public string Color { get; set; } = \"primary\";\n    [Parameter] public string TrackColor { get; set; } = \"muted\";\n    [Parameter] public IReadOnlyList<GaugeThreshold>? Thresholds { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private double Percentage => Max > Min\n        ? Math.Clamp((Value - Min) / (Max - Min) * 100.0, 0.0, 100.0)\n        : 0;\n\n    private string DisplayValue => Label ?? $\"{(int)Math.Round(Percentage)}%\";\n\n    private string ActiveColor\n    {\n        get\n        {\n            if (Thresholds is { Count: > 0 })\n            {\n                foreach (var t in Thresholds.OrderByDescending(t => t.Value))\n                {\n                    if (Value >= t.Value)\n                        return t.Color;\n                }\n            }\n            return $\"var(--color-{Color})\";\n        }\n    }\n\n    // ── Geometry helpers (InvariantCulture strings for SVG attributes) ────────\n    private double Cx => Size / 2.0;\n    private double Cy => Size / 2.0;\n    private double Radius => (Size - StrokeWidth) / 2.0;\n    private double Circumference => 2 * Math.PI * Radius;\n\n    private string CxStr => Cx.ToString(System.Globalization.CultureInfo.InvariantCulture);\n    private string CyStr => Cy.ToString(System.Globalization.CultureInfo.InvariantCulture);\n    private string RadiusStr => Radius.ToString(System.Globalization.CultureInfo.InvariantCulture);\n\n    private double ArcDegrees => Variant == GaugeVariant.Arc ? 180.0 : 270.0;\n    private double ArcLength => Circumference * ArcDegrees / 360.0;\n\n    private string StartAngleDeg => Variant == GaugeVariant.Arc ? \"-180\" : \"-135\";\n\n    private string TrackDash\n    {\n        get\n        {\n            var rest = Circumference - ArcLength;\n            return $\"{ArcLength.ToString(System.Globalization.CultureInfo.InvariantCulture)} {rest.ToString(System.Globalization.CultureInfo.InvariantCulture)}\";\n        }\n    }\n\n    private string ValueDash\n    {\n        get\n        {\n            var fill = ArcLength * Percentage / 100.0;\n            var rest = Circumference - fill;\n            return $\"{fill.ToString(System.Globalization.CultureInfo.InvariantCulture)} {rest.ToString(System.Globalization.CultureInfo.InvariantCulture)}\";\n        }\n    }\n\n    private int SvgHeight => Variant == GaugeVariant.Arc\n        ? (int)Math.Ceiling(Size / 2.0 + StrokeWidth * 1.5)\n        : Size;\n\n    private int LabelFontSize => Math.Max(10, Size / 7);\n\n    /// For Arc variant, shift label up slightly so it sits inside the semicircle.\n    private string LabelOffset => Variant == GaugeVariant.Arc\n        ? $\"padding-bottom: {(int)(Size * 0.3)}px;\"\n        : \"\";\n\n    // ── Linear geometry ───────────────────────────────────────────────────────\n    private string LinearFillWidth\n        => (Size * Percentage / 100.0).ToString(System.Globalization.CultureInfo.InvariantCulture);\n\n    private string ContainerClass\n        => $\"inline-flex flex-col items-center {Class}\".Trim();\n\n    private string ArcContainerClass\n        => $\"relative inline-flex items-center justify-center {Class}\".Trim();\n\n    private string ArcContainerStyle\n        => $\"width: {Size}px; height: {SvgHeight}px;\";\n\n    public enum GaugeVariant { Radial, Linear, Arc }\n\n    public record GaugeThreshold(double Value, string Color);\n}\n"
    }
  ],
  "slots": [],
  "serviceDependencies": [],
  "cascadingDependencies": [],
  "relatedComponents": [],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Tests/Components/Gauge/GaugeTests.cs"
  ],
  "mdSummary": "# Gauge\n\nSingle-value gauge with radial, arc, and linear variants and threshold colour bands.\n\n**Package:** `Lumeo` · **Category:** Data Display\n**Docs:** https://lumeo.nativ.sh/components/gauge\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| Gauge | Value | `double` | `` |  |\n| Gauge | Min | `double` | `0` |  |\n| Gauge | Max | `double` | `100` |  |\n| Gauge | Variant | `GaugeVariant` | `GaugeVariant.Radial` |  |\n| Gauge | Size | `int` | `120` |  |\n| Gauge | StrokeWidth | `int` | `8` |  |\n| Gauge | Label | `string?` | `` |  |\n| Gauge | ShowValue | `bool` | `true` |  |\n| Gauge | Color | `string` | `\"primary\"` |  |\n| Gauge | TrackColor | `string` | `\"muted\"` |  |\n| Gauge | Thresholds | `IReadOnlyList<GaugeThreshold>?` | `` |  |\n| Gauge | Class | `string?` | `` |  |\n| Gauge | 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<Gauge />\n```\n\n## CSS variables\n`--color-foreground`\n\n## Files\n- `UI/Gauge/Gauge.razor`\n"
}