{
  "name": "Dialog",
  "category": "Overlay",
  "subcategory": null,
  "description": "Modal dialog with header, content, footer, and focus trap.",
  "thumbnail": "/preview-cards/dialog.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/Dialog/Dialog.razor",
    "UI/Dialog/DialogClose.razor",
    "UI/Dialog/DialogContent.razor",
    "UI/Dialog/DialogDescription.razor",
    "UI/Dialog/DialogFooter.razor",
    "UI/Dialog/DialogHeader.razor",
    "UI/Dialog/DialogTitle.razor",
    "UI/Dialog/DialogTrigger.razor"
  ],
  "dependencies": [],
  "packageDependencies": [
    "Blazicons.Lucide"
  ],
  "cssVars": [
    "--color-background",
    "--color-border",
    "--color-muted",
    "--color-muted-foreground",
    "--radius"
  ],
  "api": {
    "name": "Dialog",
    "category": "Overlay",
    "subcategory": null,
    "description": "Modal dialog with header, content, footer, and focus trap.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/Dialog/Dialog.razor",
      "UI/Dialog/DialogClose.razor",
      "UI/Dialog/DialogContent.razor",
      "UI/Dialog/DialogDescription.razor",
      "UI/Dialog/DialogFooter.razor",
      "UI/Dialog/DialogHeader.razor",
      "UI/Dialog/DialogTitle.razor",
      "UI/Dialog/DialogTrigger.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "ChildContent",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Open",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OpenChanged",
        "type": "EventCallback<bool>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IsOpen",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IsOpenChanged",
        "type": "EventCallback<bool>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      }
    ],
    "events": [
      {
        "name": "OpenChanged",
        "type": "EventCallback<bool>",
        "description": null
      },
      {
        "name": "IsOpenChanged",
        "type": "EventCallback<bool>",
        "description": null
      }
    ],
    "enums": [],
    "records": [
      {
        "name": "DialogContext",
        "signature": "DialogContext(bool IsOpen, EventCallback<bool> SetOpen, string TitleId, string DescriptionId)",
        "description": null
      }
    ],
    "cssVars": [
      "--color-background",
      "--color-border",
      "--color-muted",
      "--color-muted-foreground",
      "--radius"
    ],
    "examples": [
      {
        "title": "Default",
        "code": "<Dialog @bind-Open=\"_isOpen\">\n    <DialogTrigger>\n        <Button Variant=\"Button.ButtonVariant.Outline\">Edit Profile</Button>\n    </DialogTrigger>\n    <DialogContent>\n        <DialogHeader>\n            <DialogTitle>Edit Profile</DialogTitle>\n            <DialogDescription>Make changes to your profile here.</DialogDescription>\n        </DialogHeader>\n        <Grid Columns=\"4\" Gap=\"4\" Class=\"items-center py-4\">\n            <Label Class=\"text-right\">Name</Label>\n            <Input Class=\"col-span-3\" Value=\"John Doe\" />\n            <Label Class=\"text-right\">Username</Label>\n            <Input Class=\"col-span-3\" Value=\"@johndoe\" />\n        </Grid>\n        <DialogFooter>\n            <DialogClose>\n                <Button Variant=\"Button.ButtonVariant.Outline\">Cancel</Button>\n            </DialogClose>\n            <DialogClose>\n                <Button>Save Changes</Button>\n            </DialogClose>\n        </DialogFooter>\n    </DialogContent>\n</Dialog>\n\n@code {\n    private bool _isOpen;\n}"
      },
      {
        "title": "Simple Dialog",
        "code": "<Dialog @bind-Open=\"_isOpen\">\n    <DialogTrigger>\n        <Button>Share</Button>\n    </DialogTrigger>\n    <DialogContent>\n        <DialogHeader>\n            <DialogTitle>Share this document</DialogTitle>\n            <DialogDescription>Anyone with the link can view this document.</DialogDescription>\n        </DialogHeader>\n        <Stack Gap=\"4\" Class=\"py-4\">\n            <Input Value=\"https://example.com/share/abc123\" />\n        </Stack>\n        <DialogFooter>\n            <DialogClose>\n                <Button>Copy Link</Button>\n            </DialogClose>\n        </DialogFooter>\n    </DialogContent>\n</Dialog>\n\n@code {\n    private bool _isOpen;\n}"
      },
      {
        "title": "Confirmation Dialog",
        "code": "<Dialog @bind-Open=\"_isOpen\">\n    <DialogTrigger>\n        <Button Variant=\"Button.ButtonVariant.Destructive\">\n            <Blazicon Svg=\"Lucide.Trash\" class=\"h-4 w-4\" /> Delete Account\n        </Button>\n    </DialogTrigger>\n    <DialogContent>\n        <DialogHeader>\n            <DialogTitle>Are you absolutely sure?</DialogTitle>\n            <DialogDescription>\n                This action cannot be undone. This will permanently delete your\n                account and remove your data from our servers.\n            </DialogDescription>\n        </DialogHeader>\n        <DialogFooter>\n            <DialogClose>\n                <Button Variant=\"Button.ButtonVariant.Outline\">Cancel</Button>\n            </DialogClose>\n            <DialogClose>\n                <Button Variant=\"Button.ButtonVariant.Destructive\">Yes, delete account</Button>\n            </DialogClose>\n        </DialogFooter>\n    </DialogContent>\n</Dialog>\n\n@code {\n    private bool _isOpen;\n}"
      },
      {
        "title": "Prevent Close",
        "code": "<Dialog @bind-Open=\"_preventCloseOpen\">\n    <DialogTrigger>\n        <Button Variant=\"Button.ButtonVariant.Outline\">Open Protected Dialog</Button>\n    </DialogTrigger>\n    <DialogContent PreventClose=\"true\">\n        <DialogHeader>\n            <DialogTitle>Unsaved Changes</DialogTitle>\n            <DialogDescription>You have unsaved changes. Are you sure you want to leave?</DialogDescription>\n        </DialogHeader>\n        <DialogFooter>\n            <Button Variant=\"Button.ButtonVariant.Outline\" OnClick=\"@(() => _preventCloseOpen = false)\">Discard</Button>\n            <Button OnClick=\"@(() => _preventCloseOpen = false)\">Save Changes</Button>\n        </DialogFooter>\n    </DialogContent>\n</Dialog>\n\n@code {\n    private bool _preventCloseOpen;\n}"
      }
    ],
    "subComponents": {
      "DialogClose": {
        "componentName": "DialogClose",
        "fileName": "DialogClose.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Context",
            "type": "Dialog.DialogContext",
            "default": "default!",
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "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": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DialogContent": {
        "componentName": "DialogContent",
        "fileName": "DialogContent.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [
          "IAsyncDisposable"
        ],
        "parameters": [
          {
            "name": "Context",
            "type": "Dialog.DialogContext",
            "default": "default!",
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "Shell",
            "type": "OverlayShellMarker?",
            "default": null,
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "PreventClose",
            "type": "bool",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Size",
            "type": "DialogSize",
            "default": "DialogSize.Default",
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Scrollable",
            "type": "bool",
            "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": "DialogSize",
            "values": [
              "Sm",
              "Default",
              "Lg",
              "Xl",
              "Full"
            ],
            "description": null
          }
        ],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DialogDescription": {
        "componentName": "DialogDescription",
        "fileName": "DialogDescription.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Context",
            "type": "Dialog.DialogContext",
            "default": "default!",
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "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": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DialogFooter": {
        "componentName": "DialogFooter",
        "fileName": "DialogFooter.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "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": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DialogHeader": {
        "componentName": "DialogHeader",
        "fileName": "DialogHeader.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "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": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DialogTitle": {
        "componentName": "DialogTitle",
        "fileName": "DialogTitle.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Context",
            "type": "Dialog.DialogContext",
            "default": "default!",
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "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": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      },
      "DialogTrigger": {
        "componentName": "DialogTrigger",
        "fileName": "DialogTrigger.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "Context",
            "type": "Dialog.DialogContext",
            "default": "default!",
            "description": null,
            "isCascading": true,
            "captureUnmatched": false
          },
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "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": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      }
    },
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "dialog",
  "docsUrl": "https://lumeo.nativ.sh/components/dialog",
  "sourceUrl": [
    {
      "file": "UI/Dialog/Dialog.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Dialog/Dialog.razor"
    },
    {
      "file": "UI/Dialog/DialogClose.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Dialog/DialogClose.razor"
    },
    {
      "file": "UI/Dialog/DialogContent.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Dialog/DialogContent.razor"
    },
    {
      "file": "UI/Dialog/DialogDescription.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Dialog/DialogDescription.razor"
    },
    {
      "file": "UI/Dialog/DialogFooter.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Dialog/DialogFooter.razor"
    },
    {
      "file": "UI/Dialog/DialogHeader.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Dialog/DialogHeader.razor"
    },
    {
      "file": "UI/Dialog/DialogTitle.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Dialog/DialogTitle.razor"
    },
    {
      "file": "UI/Dialog/DialogTrigger.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Dialog/DialogTrigger.razor"
    }
  ],
  "source": [
    {
      "path": "UI/Dialog/Dialog.razor",
      "content": "@namespace Lumeo\n\n@{\n    var context = new DialogContext(Open, EventCallback.Factory.Create<bool>(this, SetOpen), _titleId, _descriptionId);\n}\n\n<CascadingValue Value=\"context\" IsFixed=\"false\">\n    @ChildContent\n</CascadingValue>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public bool Open { get; set; }\n    [Parameter] public EventCallback<bool> OpenChanged { get; set; }\n\n    [Obsolete(\"Use Open instead. IsOpen will be removed in a future release.\")]\n    [Parameter] public bool IsOpen { get => Open; set => Open = value; }\n\n    [Obsolete(\"Use OpenChanged instead. IsOpenChanged will be removed in a future release.\")]\n    [Parameter] public EventCallback<bool> IsOpenChanged { get => OpenChanged; set => OpenChanged = value; }\n\n    private readonly string _titleId = $\"dialog-title-{Guid.NewGuid():N}\";\n    private readonly string _descriptionId = $\"dialog-desc-{Guid.NewGuid():N}\";\n\n    private async Task SetOpen(bool value)\n    {\n        Open = value;\n        await OpenChanged.InvokeAsync(value);\n    }\n\n    public record DialogContext(bool IsOpen, EventCallback<bool> SetOpen, string TitleId, string DescriptionId);\n}\n"
    },
    {
      "path": "UI/Dialog/DialogClose.razor",
      "content": "@namespace Lumeo\n\n<div class=\"@CssClass\" @onclick=\"Close\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@code {\n    [CascadingParameter] public Dialog.DialogContext Context { get; set; } = default!;\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"inline-flex {Class}\".Trim();\n\n    private async Task Close() => await Context.SetOpen.InvokeAsync(false);\n}\n"
    },
    {
      "path": "UI/Dialog/DialogContent.razor",
      "content": "@namespace Lumeo\n@using Lumeo.Services\n@implements IAsyncDisposable\n\n@if (Shell is not null)\n{\n    @* See OverlayShellMarker — host DialogContent already painted the shell.\n       Pass children through to avoid a second backdrop + panel. *@\n    @ChildContent\n}\nelse if (Context.IsOpen)\n{\n    <div class=\"fixed inset-0 z-50 flex items-center justify-center\">\n        <!-- Backdrop -->\n        <div class=\"fixed inset-0 bg-black/80 animate-fade-in\" @onclick=\"HandleBackdropClick\"></div>\n        <!-- Content -->\n        <div id=\"@_contentId\" class=\"@CssClass\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"@Context.TitleId\" aria-describedby=\"@Context.DescriptionId\" @onkeydown=\"HandleKeyDown\" tabindex=\"-1\" @attributes=\"AdditionalAttributes\">\n            @if (Scrollable)\n            {\n                <div class=\"max-h-[85vh] overflow-y-auto\">\n                    @ChildContent\n                </div>\n            }\n            else\n            {\n                @ChildContent\n            }\n            @if (!PreventClose)\n            {\n                <button class=\"absolute right-2 top-2 sm:right-4 sm:top-4 inline-flex items-center justify-center rounded-sm h-11 w-11 sm:h-6 sm:w-6 opacity-70 transition-opacity hover:opacity-100 focus:outline-none\" @onclick=\"Close\">\n                    <Blazicon Svg=\"Lucide.X\" class=\"h-4 w-4\" />\n                    <span class=\"sr-only\">@L[\"Dialog.Close\"]</span>\n                </button>\n            }\n        </div>\n    </div>\n}\n\n@inject ComponentInteropService Interop\n@inject Lumeo.Services.Localization.ILumeoLocalizer L\n\n@code {\n    [CascadingParameter] public Dialog.DialogContext Context { get; set; } = default!;\n    [CascadingParameter] public OverlayShellMarker? Shell { get; set; }\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public bool PreventClose { get; set; }\n    [Parameter] public DialogSize Size { get; set; } = DialogSize.Default;\n    [Parameter] public bool Scrollable { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private readonly string _contentId = $\"dialog-{Guid.NewGuid():N}\";\n    private bool _wasOpen;\n\n    private string SizeClass => Size switch\n    {\n        DialogSize.Sm => \"max-w-sm\",\n        DialogSize.Default => \"max-w-lg\",\n        DialogSize.Lg => \"max-w-2xl\",\n        DialogSize.Xl => \"max-w-4xl\",\n        DialogSize.Full => \"max-w-[calc(100vw-2rem)] max-h-[calc(100vh-2rem)]\",\n        _ => \"max-w-lg\"\n    };\n\n    private string CssClass => $\"relative z-50 grid w-full {SizeClass} gap-4 bg-background p-6 shadow-lg animate-zoom-in sm:rounded-lg {Class}\".Trim();\n\n    protected override async Task OnAfterRenderAsync(bool firstRender)\n    {\n        // Passthrough mode — host DialogContent owns lifecycle effects.\n        if (Shell is not null) return;\n\n        if (Context.IsOpen && !_wasOpen)\n        {\n            await Interop.LockScroll();\n            await Interop.SetupFocusTrap(_contentId);\n            _wasOpen = true;\n        }\n        else if (!Context.IsOpen && _wasOpen)\n        {\n            await Cleanup();\n            _wasOpen = false;\n        }\n    }\n\n    private async Task Close() => await Context.SetOpen.InvokeAsync(false);\n\n    private async Task HandleBackdropClick()\n    {\n        if (!PreventClose) await Close();\n    }\n\n    private async Task HandleKeyDown(KeyboardEventArgs e)\n    {\n        if (e.Key == \"Escape\" && !PreventClose)\n        {\n            await Close();\n        }\n    }\n\n    private async Task Cleanup()\n    {\n        try\n        {\n            await Interop.RemoveFocusTrap(_contentId);\n            await Interop.UnlockScroll();\n        }\n        catch (JSDisconnectedException) { }\n    }\n\n    public async ValueTask DisposeAsync()\n    {\n        if (_wasOpen)\n        {\n            await Cleanup();\n        }\n    }\n\n    public enum DialogSize { Sm, Default, Lg, Xl, Full }\n}\n"
    },
    {
      "path": "UI/Dialog/DialogDescription.razor",
      "content": "@namespace Lumeo\n\n<p id=\"@Context.DescriptionId\" class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</p>\n\n@code {\n    [CascadingParameter] public Dialog.DialogContext Context { get; set; } = default!;\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"text-sm text-muted-foreground {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/Dialog/DialogFooter.razor",
      "content": "@namespace Lumeo\n\n<div class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"flex items-center justify-end gap-2 mt-6 pt-4 border-t border-border/40 {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/Dialog/DialogHeader.razor",
      "content": "@namespace Lumeo\n\n<div class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"flex flex-col space-y-1.5 text-center sm:text-left {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/Dialog/DialogTitle.razor",
      "content": "@namespace Lumeo\n\n<h2 id=\"@Context.TitleId\" class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</h2>\n\n@code {\n    [CascadingParameter] public Dialog.DialogContext Context { get; set; } = default!;\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"text-lg font-semibold leading-none tracking-tight {Class}\".Trim();\n}\n"
    },
    {
      "path": "UI/Dialog/DialogTrigger.razor",
      "content": "@namespace Lumeo\n\n<div class=\"@CssClass\" @onclick=\"Open\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@code {\n    [CascadingParameter] public Dialog.DialogContext Context { get; set; } = default!;\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    private string CssClass => $\"inline-flex {Class}\".Trim();\n\n    private async Task Open() => await Context.SetOpen.InvokeAsync(true);\n}\n"
    }
  ],
  "slots": [
    {
      "name": "ChildContent",
      "owner": "Dialog",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DialogClose",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DialogContent",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DialogDescription",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DialogFooter",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DialogHeader",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DialogTitle",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DialogTrigger",
      "type": "RenderFragment?",
      "description": null
    }
  ],
  "serviceDependencies": [
    {
      "service": "ComponentInteropService",
      "namespace": ""
    },
    {
      "service": "ILumeoLocalizer",
      "namespace": "Lumeo.Services.Localization"
    }
  ],
  "cascadingDependencies": [
    {
      "name": "Context",
      "type": "Dialog.DialogContext",
      "required": true
    },
    {
      "name": "Shell",
      "type": "OverlayShellMarker?",
      "required": false
    }
  ],
  "relatedComponents": [
    {
      "name": "DialogClose",
      "reason": "sub-component"
    },
    {
      "name": "DialogContent",
      "reason": "sub-component"
    },
    {
      "name": "DialogDescription",
      "reason": "sub-component"
    },
    {
      "name": "DialogFooter",
      "reason": "sub-component"
    },
    {
      "name": "DialogHeader",
      "reason": "sub-component"
    },
    {
      "name": "DialogTitle",
      "reason": "sub-component"
    },
    {
      "name": "DialogTrigger",
      "reason": "sub-component"
    }
  ],
  "keyboardInteractions": [
    {
      "key": "Escape",
      "action": "HandleKeyDown handles Escape in DialogContent.razor"
    }
  ],
  "tests": [
    "tests/Lumeo.Tests.E2E/Smokes/DialogFocusTrapTests.cs",
    "tests/Lumeo.Tests/Components/Dialog/DialogTests.cs",
    "tests/Lumeo.Tests/Contract/ComponentContractTests.cs",
    "tests/Lumeo.Tests/Services/OverlayServiceTests.cs"
  ],
  "mdSummary": "# Dialog\n\nModal dialog with header, content, footer, and focus trap.\n\n**Package:** `Lumeo` · **Category:** Overlay\n**Docs:** https://lumeo.nativ.sh/components/dialog\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| Dialog | ChildContent | `RenderFragment?` | `` |  |\n| Dialog | Open | `bool` | `` |  |\n| Dialog | OpenChanged | `EventCallback<bool>` | `` |  |\n| Dialog | IsOpen | `bool` | `` |  |\n| Dialog | IsOpenChanged | `EventCallback<bool>` | `` |  |\n| DialogClose | Context | `Dialog.DialogContext` | `default!` |  |\n| DialogClose | ChildContent | `RenderFragment?` | `` |  |\n| DialogClose | Class | `string?` | `` |  |\n| DialogClose | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DialogContent | Context | `Dialog.DialogContext` | `default!` |  |\n| DialogContent | Shell | `OverlayShellMarker?` | `` |  |\n| DialogContent | ChildContent | `RenderFragment?` | `` |  |\n| DialogContent | PreventClose | `bool` | `` |  |\n| DialogContent | Size | `DialogSize` | `DialogSize.Default` |  |\n| DialogContent | Scrollable | `bool` | `` |  |\n| DialogContent | Class | `string?` | `` |  |\n| DialogContent | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DialogDescription | Context | `Dialog.DialogContext` | `default!` |  |\n| DialogDescription | ChildContent | `RenderFragment?` | `` |  |\n| DialogDescription | Class | `string?` | `` |  |\n| DialogDescription | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DialogFooter | ChildContent | `RenderFragment?` | `` |  |\n| DialogFooter | Class | `string?` | `` |  |\n| DialogFooter | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DialogHeader | ChildContent | `RenderFragment?` | `` |  |\n| DialogHeader | Class | `string?` | `` |  |\n| DialogHeader | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DialogTitle | Context | `Dialog.DialogContext` | `default!` |  |\n| DialogTitle | ChildContent | `RenderFragment?` | `` |  |\n| DialogTitle | Class | `string?` | `` |  |\n| DialogTitle | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DialogTrigger | Context | `Dialog.DialogContext` | `default!` |  |\n| DialogTrigger | ChildContent | `RenderFragment?` | `` |  |\n| DialogTrigger | Class | `string?` | `` |  |\n| DialogTrigger | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- `ChildContent` (Dialog) — RenderFragment slot\n- `ChildContent` (DialogClose) — RenderFragment slot\n- `ChildContent` (DialogContent) — RenderFragment slot\n- `ChildContent` (DialogDescription) — RenderFragment slot\n- `ChildContent` (DialogFooter) — RenderFragment slot\n- `ChildContent` (DialogHeader) — RenderFragment slot\n- `ChildContent` (DialogTitle) — RenderFragment slot\n- `ChildContent` (DialogTrigger) — RenderFragment slot\n\n## Events\n- `OpenChanged` (`EventCallback<bool>`)\n- `IsOpenChanged` (`EventCallback<bool>`)\n\n## Sub-components\n- `DialogClose`, `DialogContent`, `DialogDescription`, `DialogFooter`, `DialogHeader`, `DialogTitle`, `DialogTrigger`\n\n## Cascading values it expects\n- `Context` (`Dialog.DialogContext`)\n- `Shell` (`OverlayShellMarker?`)\n\n## Services it injects\n- `ComponentInteropService` ()\n- `ILumeoLocalizer` (Lumeo.Services.Localization)\n\n## Keyboard\n- `Escape` — HandleKeyDown handles Escape in DialogContent.razor\n\n## Example\n```razor\n<Dialog />\n```\n\n## CSS variables\n`--color-background`, `--color-border`, `--color-muted`, `--color-muted-foreground`, `--radius`\n\n## Files\n- `UI/Dialog/Dialog.razor`\n- `UI/Dialog/DialogClose.razor`\n- `UI/Dialog/DialogContent.razor`\n- `UI/Dialog/DialogDescription.razor`\n- `UI/Dialog/DialogFooter.razor`\n- `UI/Dialog/DialogHeader.razor`\n- `UI/Dialog/DialogTitle.razor`\n- `UI/Dialog/DialogTrigger.razor`\n"
}