{
  "name": "Alert",
  "category": "Feedback",
  "subcategory": null,
  "description": "Inline callout for status, warning, or informational messages.",
  "thumbnail": "/preview-cards/alert.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/Alert/Alert.razor"
  ],
  "dependencies": [],
  "packageDependencies": [
    "Blazicons.Lucide"
  ],
  "cssVars": [
    "--color-background",
    "--color-border",
    "--color-destructive",
    "--color-foreground",
    "--color-primary",
    "--color-ring",
    "--radius"
  ],
  "api": {
    "name": "Alert",
    "category": "Feedback",
    "subcategory": null,
    "description": "Inline callout for status, warning, or informational messages.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/Alert/Alert.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [
      "IDisposable"
    ],
    "parameters": [
      {
        "name": "ChildContent",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Variant",
        "type": "AlertVariant",
        "default": "AlertVariant.Default",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Size",
        "type": "AlertSize",
        "default": "AlertSize.Medium",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IsDismissible",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OnDismiss",
        "type": "EventCallback",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Title",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Description",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IconContent",
        "type": "RenderFragment?",
        "default": null,
        "description": "Icon slot. Named IconContent to avoid shadowing the &lt;Icon&gt; component.",
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "ShowIcon",
        "type": "bool",
        "default": "true",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "AutoDismissMs",
        "type": "int?",
        "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": [
      {
        "name": "OnDismiss",
        "type": "EventCallback",
        "description": null
      }
    ],
    "enums": [
      {
        "name": "AlertVariant",
        "values": [
          "Default",
          "Destructive",
          "Success",
          "Warning",
          "Info"
        ],
        "description": null
      },
      {
        "name": "AlertSize",
        "values": [
          "Small",
          "Medium",
          "Large"
        ],
        "description": null
      }
    ],
    "records": [],
    "cssVars": [
      "--color-background",
      "--color-border",
      "--color-destructive",
      "--color-foreground",
      "--color-primary",
      "--color-ring",
      "--radius"
    ],
    "examples": [
      {
        "title": "Default",
        "code": "<Alert>\n    <Heading Level=\"5\" Size=\"sm\" Weight=\"medium\" Class=\"mb-1 leading-none tracking-tight\">Heads up!</Heading>\n    <Lumeo.Text Size=\"sm\" Leading=\"relaxed\">You can add components to your app using the CLI.</Lumeo.Text>\n</Alert>"
      },
      {
        "title": "Destructive",
        "code": "<Alert Variant=\"Alert.AlertVariant.Destructive\">\n    <Heading Level=\"5\" Size=\"sm\" Weight=\"medium\" Class=\"mb-1 leading-none tracking-tight\">Error</Heading>\n    <Lumeo.Text Size=\"sm\" Leading=\"relaxed\">Your session has expired. Please log in again.</Lumeo.Text>\n</Alert>"
      },
      {
        "title": "With Icon",
        "code": "<Alert>\n    <Flex Gap=\"3\">\n        <Blazicon Svg=\"Lucide.Info\" class=\"h-4 w-4 mt-0.5\" />\n        <Stack Gap=\"0\">\n            <Heading Level=\"5\" Size=\"sm\" Weight=\"medium\" Class=\"mb-1 leading-none tracking-tight\">Information</Heading>\n            <Lumeo.Text Size=\"sm\" Leading=\"relaxed\">This action will update your preferences.</Lumeo.Text>\n        </Stack>\n    </Flex>\n</Alert>\n<Alert Variant=\"Alert.AlertVariant.Destructive\">\n    <Flex Gap=\"3\">\n        <Blazicon Svg=\"Lucide.CircleAlert\" class=\"h-4 w-4 mt-0.5\" />\n        <Stack Gap=\"0\">\n            <Heading Level=\"5\" Size=\"sm\" Weight=\"medium\" Class=\"mb-1 leading-none tracking-tight\">Something went wrong</Heading>\n            <Lumeo.Text Size=\"sm\" Leading=\"relaxed\">Could not save your changes. Please try again.</Lumeo.Text>\n        </Stack>\n    </Flex>\n</Alert>"
      },
      {
        "title": "With Action",
        "code": "<Alert>\n    <Flex Align=\"start\" Justify=\"between\" Gap=\"4\">\n        <Flex Gap=\"3\">\n            <Blazicon Svg=\"Lucide.Bell\" class=\"h-4 w-4 mt-0.5 text-primary\" />\n            <Stack Gap=\"0\">\n                <Heading Level=\"5\" Size=\"sm\" Weight=\"medium\" Class=\"mb-1 leading-none tracking-tight\">New feature available</Heading>\n                <Lumeo.Text Size=\"sm\" Leading=\"relaxed\">Dark mode is now available for all users.</Lumeo.Text>\n            </Stack>\n        </Flex>\n        <Button Variant=\"Button.ButtonVariant.Outline\" Size=\"Button.ButtonSize.Sm\">Try it</Button>\n    </Flex>\n</Alert>"
      }
    ],
    "subComponents": {},
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "alert",
  "docsUrl": "https://lumeo.nativ.sh/components/alert",
  "sourceUrl": [
    {
      "file": "UI/Alert/Alert.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Alert/Alert.razor"
    }
  ],
  "source": [
    {
      "path": "UI/Alert/Alert.razor",
      "content": "@namespace Lumeo\n@implements IDisposable\n\n@if (!_isDismissed)\n{\n    <div role=\"alert\" class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n        <div class=\"flex gap-3\">\n            @if (IconContent is not null)\n            {\n                <div class=\"shrink-0 mt-0.5\">\n                    @IconContent\n                </div>\n            }\n            else if (ShowIcon)\n            {\n                <div class=\"shrink-0 mt-0.5\">\n                    @switch (Variant)\n                    {\n                        case AlertVariant.Destructive:\n                            <Blazicon Svg=\"Lucide.TriangleAlert\" class=\"@IconSizeClass\" />\n                            break;\n                        case AlertVariant.Success:\n                            <Blazicon Svg=\"Lucide.CircleCheck\" class=\"@IconSizeClass\" />\n                            break;\n                        case AlertVariant.Warning:\n                            <Blazicon Svg=\"Lucide.TriangleAlert\" class=\"@IconSizeClass\" />\n                            break;\n                        case AlertVariant.Info:\n                            <Blazicon Svg=\"Lucide.Info\" class=\"@IconSizeClass\" />\n                            break;\n                        default:\n                            <Blazicon Svg=\"Lucide.Info\" class=\"@IconSizeClass\" />\n                            break;\n                    }\n                </div>\n            }\n            <div class=\"flex-1 min-w-0\">\n                @if (!string.IsNullOrEmpty(Title))\n                {\n                    <h5 class=\"@TitleClass\">@Title</h5>\n                }\n                @if (!string.IsNullOrEmpty(Description))\n                {\n                    <div class=\"@DescriptionClass\">@Description</div>\n                }\n                @ChildContent\n            </div>\n            @if (IsDismissible)\n            {\n                <div class=\"shrink-0\">\n                    <button type=\"button\" class=\"rounded-md hover:bg-foreground/10 focus:outline-none focus:ring-1 focus:ring-ring p-0.5\" @onclick=\"Dismiss\" aria-label=\"Dismiss\">\n                        <Blazicon Svg=\"Lucide.X\" class=\"@IconSizeClass\" />\n                    </button>\n                </div>\n            }\n        </div>\n    </div>\n}\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public AlertVariant Variant { get; set; } = AlertVariant.Default;\n    [Parameter] public AlertSize Size { get; set; } = AlertSize.Medium;\n    [Parameter] public bool IsDismissible { get; set; }\n    [Parameter] public EventCallback OnDismiss { get; set; }\n    [Parameter] public string? Title { get; set; }\n    [Parameter] public string? Description { get; set; }\n    /// <summary>Icon slot. Named <c>IconContent</c> to avoid shadowing the <c>&lt;Icon&gt;</c> component.</summary>\n    [Parameter] public RenderFragment? IconContent { get; set; }\n\n    [Parameter] public bool ShowIcon { get; set; } = true;\n    [Parameter] public int? AutoDismissMs { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private bool _isDismissed;\n    private volatile bool _disposed;\n    private CancellationTokenSource? _autoDismissCts;\n\n    protected override void OnInitialized()\n    {\n        if (AutoDismissMs.HasValue && AutoDismissMs.Value > 0)\n        {\n            _autoDismissCts = new CancellationTokenSource();\n            var timeout = AutoDismissMs.Value;\n            var token = _autoDismissCts.Token;\n            // Dispatch via SafeAsyncDispatcher so any outer-task fault (e.g. circuit\n            // already disposed) is caught and never surfaces as an unobserved task.\n            SafeAsyncDispatcher.FireAndForget(\n                fn => InvokeAsync(fn),\n                () => RunAutoDismissAsync(timeout, token),\n                \"Lumeo.Alert\");\n        }\n    }\n\n    private async Task RunAutoDismissAsync(int timeout, CancellationToken token)\n    {\n        try\n        {\n            await Task.Delay(timeout, token).ConfigureAwait(true);\n        }\n        catch (TaskCanceledException) { return; }\n        catch (OperationCanceledException) { return; }\n\n        if (_disposed || token.IsCancellationRequested) return;\n        if (_isDismissed) return;\n        _isDismissed = true;\n        await OnDismiss.InvokeAsync();\n        if (_disposed) return;\n        StateHasChanged();\n    }\n\n    // Border baseline kept at /60 so the unfilled (Default variant) alert still reads as an outlined callout;\n    // colored variants knock it softer since their tinted background already carries the visual weight.\n    private string CssClass => $\"relative w-full rounded-lg border border-border/60 {SizePaddingClass} text-sm {VariantClasses} {Class}\".Trim();\n\n    private string SizePaddingClass => Size switch\n    {\n        AlertSize.Small => \"px-3 py-2\",\n        AlertSize.Large => \"px-5 py-4\",\n        _ => \"px-4 py-3\"\n    };\n\n    private string IconSizeClass => Size switch\n    {\n        AlertSize.Small => \"h-3.5 w-3.5\",\n        AlertSize.Large => \"h-5 w-5\",\n        _ => \"h-4 w-4\"\n    };\n\n    private string TitleClass => Size switch\n    {\n        AlertSize.Small => \"mb-0.5 text-xs font-medium leading-none tracking-tight\",\n        AlertSize.Large => \"mb-1.5 text-base font-medium leading-none tracking-tight\",\n        _ => \"mb-1 font-medium leading-none tracking-tight\"\n    };\n\n    private string DescriptionClass => Size switch\n    {\n        AlertSize.Small => \"text-xs opacity-90\",\n        AlertSize.Large => \"text-sm opacity-90\",\n        _ => \"text-sm opacity-90\"\n    };\n\n    private string VariantClasses => Variant switch\n    {\n        AlertVariant.Default => \"bg-background text-foreground\",\n        AlertVariant.Destructive => \"border-destructive/50 text-destructive\",\n        AlertVariant.Success => \"border-success/50 bg-success-light text-success-text\",\n        AlertVariant.Warning => \"border-warning/50 bg-warning-light text-warning-text\",\n        AlertVariant.Info => \"border-primary/50 bg-primary/10 text-primary\",\n        _ => \"\"\n    };\n\n    private async Task Dismiss()\n    {\n        if (_isDismissed) return;\n        try { _autoDismissCts?.Cancel(); } catch (ObjectDisposedException) { }\n        _isDismissed = true;\n        await OnDismiss.InvokeAsync();\n    }\n\n    public void Dispose()\n    {\n        _disposed = true;\n        try { _autoDismissCts?.Cancel(); } catch (ObjectDisposedException) { }\n        _autoDismissCts?.Dispose();\n        _autoDismissCts = null;\n    }\n\n    public enum AlertVariant { Default, Destructive, Success, Warning, Info }\n    public enum AlertSize { Small, Medium, Large }\n}\n"
    }
  ],
  "slots": [
    {
      "name": "ChildContent",
      "owner": "Alert",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "IconContent",
      "owner": "Alert",
      "type": "RenderFragment?",
      "description": "Icon slot. Named IconContent to avoid shadowing the &lt;Icon&gt; component."
    }
  ],
  "serviceDependencies": [],
  "cascadingDependencies": [],
  "relatedComponents": [],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Tests/Components/Alert/AlertAutoDismissTests.cs",
    "tests/Lumeo.Tests/Components/Alert/AlertTests.cs",
    "tests/Lumeo.Tests/Components/AlertDialog/AlertDialogTests.cs"
  ],
  "mdSummary": "# Alert\n\nInline callout for status, warning, or informational messages.\n\n**Package:** `Lumeo` · **Category:** Feedback\n**Docs:** https://lumeo.nativ.sh/components/alert\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| Alert | ChildContent | `RenderFragment?` | `` |  |\n| Alert | Variant | `AlertVariant` | `AlertVariant.Default` |  |\n| Alert | Size | `AlertSize` | `AlertSize.Medium` |  |\n| Alert | IsDismissible | `bool` | `` |  |\n| Alert | OnDismiss | `EventCallback` | `` |  |\n| Alert | Title | `string?` | `` |  |\n| Alert | Description | `string?` | `` |  |\n| Alert | IconContent | `RenderFragment?` | `` | Icon slot. Named IconContent to avoid shadowing the &lt;Icon&gt; component. |\n| Alert | ShowIcon | `bool` | `true` |  |\n| Alert | AutoDismissMs | `int?` | `` |  |\n| Alert | Class | `string?` | `` |  |\n| Alert | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- `ChildContent` (Alert) — RenderFragment slot\n- `IconContent` (Alert) — Icon slot. Named IconContent to avoid shadowing the &lt;Icon&gt; component.\n\n## Events\n- `OnDismiss` (`EventCallback`)\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<Alert />\n```\n\n## CSS variables\n`--color-background`, `--color-border`, `--color-destructive`, `--color-foreground`, `--color-primary`, `--color-ring`, `--radius`\n\n## Files\n- `UI/Alert/Alert.razor`\n"
}