{
  "name": "Sparkles",
  "category": "Motion",
  "subcategory": null,
  "description": "Decorative sparkle particle animation.",
  "thumbnail": "/preview-cards/sparkles.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo.Motion",
  "files": [
    "UI/Sparkles/Sparkles.razor"
  ],
  "dependencies": [],
  "packageDependencies": [],
  "cssVars": [
    "--color-foreground"
  ],
  "api": {
    "name": "Sparkles",
    "category": "Motion",
    "subcategory": null,
    "description": "Decorative sparkle particle animation.",
    "nugetPackage": "Lumeo.Motion",
    "files": [
      "UI/Sparkles/Sparkles.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "ChildContent",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Count",
        "type": "int",
        "default": "5",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "MinSize",
        "type": "int",
        "default": "6",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "MaxSize",
        "type": "int",
        "default": "14",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Color",
        "type": "string",
        "default": "\"var(--color-primary)\"",
        "description": "CSS color of the sparkles — defaults to var(--color-primary).",
        "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": "Sparkle",
        "signature": "Sparkle(double Top, double Left, int Size, int Delay, int Duration)",
        "description": null
      }
    ],
    "cssVars": [
      "--color-foreground"
    ],
    "examples": [
      {
        "title": "Text Wrap",
        "code": "<Sparkles>\n    <span class=\"text-lg font-semibold\">New Feature</span>\n</Sparkles>\n\n<Sparkles Count=\"3\">\n    <Badge>Pro</Badge>\n</Sparkles>"
      },
      {
        "title": "Custom Color",
        "code": "<Sparkles Color=\"var(--color-primary)\">\n    <span class=\"text-lg font-semibold text-primary\">Primary</span>\n</Sparkles>\n\n<Sparkles Color=\"oklch(0.7 0.2 30)\">\n    <span class=\"text-lg font-semibold\">Amber</span>\n</Sparkles>"
      },
      {
        "title": "Dense Sparkles",
        "code": "<Sparkles Count=\"12\" MinSize=\"8\" MaxSize=\"18\">\n    <Heading Level=\"2\">Magical Heading</Heading>\n</Sparkles>"
      },
      {
        "title": "Subtle (Few Sparkles)",
        "code": "<Sparkles Count=\"2\" MinSize=\"4\" MaxSize=\"8\">\n    <Button>Upgrade</Button>\n</Sparkles>"
      }
    ],
    "subComponents": {},
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "sparkles",
  "docsUrl": "https://lumeo.nativ.sh/components/sparkles",
  "sourceUrl": [
    {
      "file": "UI/Sparkles/Sparkles.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo.Motion/UI/Sparkles/Sparkles.razor"
    }
  ],
  "source": [
    {
      "path": "UI/Sparkles/Sparkles.razor",
      "content": "@namespace Lumeo\n\n<span class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @foreach (var sp in _sparkles)\n    {\n        <span class=\"lumeo-sparkle\"\n              style=\"top:@(sp.Top)%; left:@(sp.Left)%; width:@(sp.Size)px; height:@(sp.Size)px; animation-delay:@(sp.Delay)ms; animation-duration:@(sp.Duration)ms; color:@Color;\">\n            <svg viewBox=\"0 0 24 24\" width=\"100%\" height=\"100%\" fill=\"currentColor\" aria-hidden=\"true\">\n                <path d=\"M12 0 L14 10 L24 12 L14 14 L12 24 L10 14 L0 12 L10 10 Z\" />\n            </svg>\n        </span>\n    }\n    <span class=\"relative z-10\">@ChildContent</span>\n</span>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public int Count { get; set; } = 5;\n    [Parameter] public int MinSize { get; set; } = 6;\n    [Parameter] public int MaxSize { get; set; } = 14;\n\n    /// <summary>CSS color of the sparkles — defaults to <c>var(--color-primary)</c>.</summary>\n    [Parameter] public string Color { get; set; } = \"var(--color-primary)\";\n\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private readonly string _elementId = $\"lumeo-sparkles-{Guid.NewGuid():N}\";\n    private List<Sparkle> _sparkles = new();\n    private int _lastSeed;\n\n    // If the consumer passes their own positioning utility (absolute/fixed/sticky), skip the marker class\n    // that forces `position: relative` — unlayered rules in lumeo.css always beat Tailwind's layered utilities,\n    // so the only reliable way to let \"absolute inset-0\" through is to not emit the conflicting rule at all.\n    private string CssClass\n    {\n        get\n        {\n            var overridesPosition = !string.IsNullOrEmpty(Class)\n                && (Class.Contains(\"absolute\") || Class.Contains(\"fixed\") || Class.Contains(\"sticky\"));\n            var baseClass = overridesPosition ? null : \"lumeo-sparkles\";\n            return string.Join(\" \", new[] { baseClass, Class }.Where(s => !string.IsNullOrWhiteSpace(s)));\n        }\n    }\n\n    protected override void OnParametersSet()\n    {\n        // Seeded deterministic placement — stable across re-renders so sparkles do not \"jump\".\n        var seed = GetStableSeed();\n        if (_sparkles.Count == Count && seed == _lastSeed && _sparkles.All(s => s.Size >= MinSize && s.Size <= MaxSize))\n        {\n            return;\n        }\n        _lastSeed = seed;\n        var rng = new Random(seed);\n        _sparkles = Enumerable.Range(0, Math.Max(0, Count)).Select(_ => new Sparkle(\n            Top: Math.Round(rng.NextDouble() * 90 + 5, 2),\n            Left: Math.Round(rng.NextDouble() * 90 + 5, 2),\n            Size: rng.Next(MinSize, Math.Max(MinSize + 1, MaxSize + 1)),\n            Delay: rng.Next(0, 2000),\n            Duration: rng.Next(1600, 2800)\n        )).ToList();\n    }\n\n    private int GetStableSeed()\n    {\n        // Stable hash from element id + Count; avoids relying on GetHashCode which is randomized between runs.\n        var src = $\"{_elementId}:{Count}:{MinSize}:{MaxSize}\";\n        unchecked\n        {\n            var hash = 2166136261u;\n            foreach (var c in src)\n            {\n                hash ^= c;\n                hash *= 16777619u;\n            }\n            return (int)hash;\n        }\n    }\n\n    private record Sparkle(double Top, double Left, int Size, int Delay, int Duration);\n}\n"
    }
  ],
  "slots": [
    {
      "name": "ChildContent",
      "owner": "Sparkles",
      "type": "RenderFragment?",
      "description": null
    }
  ],
  "serviceDependencies": [],
  "cascadingDependencies": [],
  "relatedComponents": [],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Tests/Components/Sparkles/SparklesTests.cs"
  ],
  "mdSummary": "# Sparkles\n\nDecorative sparkle particle animation.\n\n**Package:** `Lumeo.Motion` · **Category:** Motion\n**Docs:** https://lumeo.nativ.sh/components/sparkles\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| Sparkles | ChildContent | `RenderFragment?` | `` |  |\n| Sparkles | Count | `int` | `5` |  |\n| Sparkles | MinSize | `int` | `6` |  |\n| Sparkles | MaxSize | `int` | `14` |  |\n| Sparkles | Color | `string` | `\"var(--color-primary)\"` | CSS color of the sparkles — defaults to var(--color-primary). |\n| Sparkles | Class | `string?` | `` |  |\n| Sparkles | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- `ChildContent` (Sparkles) — 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<Sparkles />\n```\n\n## CSS variables\n`--color-foreground`\n\n## Files\n- `UI/Sparkles/Sparkles.razor`\n"
}