{
  "name": "Affix",
  "category": "Navigation",
  "subcategory": null,
  "description": "Pins an element to the viewport edge as the user scrolls.",
  "thumbnail": "/preview-cards/affix.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo",
  "files": [
    "UI/Affix/Affix.razor"
  ],
  "dependencies": [],
  "packageDependencies": [],
  "cssVars": [
    "--color-foreground"
  ],
  "api": {
    "name": "Affix",
    "category": "Navigation",
    "subcategory": null,
    "description": "Pins an element to the viewport edge as the user scrolls.",
    "nugetPackage": "Lumeo",
    "files": [
      "UI/Affix/Affix.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [
      "IAsyncDisposable"
    ],
    "parameters": [
      {
        "name": "ChildContent",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OffsetTop",
        "type": "int",
        "default": "0",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OffsetBottom",
        "type": "int?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Target",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OnChange",
        "type": "EventCallback<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": [
      {
        "name": "OnChange",
        "type": "EventCallback<bool>",
        "description": null
      }
    ],
    "enums": [],
    "records": [],
    "cssVars": [
      "--color-foreground"
    ],
    "examples": [
      {
        "title": "Basic Affix",
        "code": "<Affix OffsetTop=\"80\">\n    <div class=\"bg-background border rounded-lg p-4 shadow-sm\">\n        This content sticks at 80px from top.\n    </div>\n</Affix>"
      },
      {
        "title": "Interactive: Anchor & Offset",
        "code": "@* Top anchor *@\n<Affix OffsetTop=\"80\">\n    <Badge Class=\"px-4 py-1.5 text-sm shadow\">Affixed — Top 80px</Badge>\n</Affix>\n\n@* Bottom anchor *@\n<Affix OffsetBottom=\"40\">\n    <Badge Class=\"px-4 py-1.5 text-sm shadow\">Affixed — Bottom 40px</Badge>\n</Affix>"
      }
    ],
    "subComponents": {},
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "affix",
  "docsUrl": "https://lumeo.nativ.sh/components/affix",
  "sourceUrl": [
    {
      "file": "UI/Affix/Affix.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo/UI/Affix/Affix.razor"
    }
  ],
  "source": [
    {
      "path": "UI/Affix/Affix.razor",
      "content": "@namespace Lumeo\n@implements IAsyncDisposable\n\n<div id=\"@_elementId\" class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    @ChildContent\n</div>\n\n@inject ComponentInteropService Interop\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter] public int OffsetTop { get; set; } = 0;\n    [Parameter] public int? OffsetBottom { get; set; }\n    [Parameter] public string? Target { get; set; }\n    [Parameter] public EventCallback<bool> OnChange { 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 _elementId = $\"affix-{Guid.NewGuid():N}\";\n    private bool _registered;\n    private bool _isFixed;\n\n    private string CssClass => Class ?? \"\";\n\n    protected override async Task OnAfterRenderAsync(bool firstRender)\n    {\n        if (!firstRender) return;\n        if (_registered) return;\n        try\n        {\n            await Interop.RegisterAffix(_elementId, OffsetTop, OffsetBottom, Target, async (isFixed) =>\n            {\n                if (_isFixed != isFixed)\n                {\n                    _isFixed = isFixed;\n                    await OnChange.InvokeAsync(isFixed);\n                    await InvokeAsync(StateHasChanged);\n                }\n            });\n            _registered = true;\n        }\n        catch (JSDisconnectedException) { }\n        catch (ObjectDisposedException) { }\n    }\n\n    public async ValueTask DisposeAsync()\n    {\n        if (_registered)\n        {\n            try { await Interop.UnregisterAffix(_elementId); } catch (JSDisconnectedException) { }\n        }\n    }\n}\n"
    }
  ],
  "slots": [
    {
      "name": "ChildContent",
      "owner": "Affix",
      "type": "RenderFragment?",
      "description": null
    }
  ],
  "serviceDependencies": [
    {
      "service": "ComponentInteropService",
      "namespace": ""
    }
  ],
  "cascadingDependencies": [],
  "relatedComponents": [],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Docs.Tests/Helpers/DocsTestContext.cs",
    "tests/Lumeo.Tests/Components/Affix/AffixTests.cs",
    "tests/Lumeo.Tests/Services/Interop/InteropAdapterTests.cs",
    "tests/Lumeo.Tests/Services/StrictInteropTests.cs"
  ],
  "mdSummary": "# Affix\n\nPins an element to the viewport edge as the user scrolls.\n\n**Package:** `Lumeo` · **Category:** Navigation\n**Docs:** https://lumeo.nativ.sh/components/affix\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| Affix | ChildContent | `RenderFragment?` | `` |  |\n| Affix | OffsetTop | `int` | `0` |  |\n| Affix | OffsetBottom | `int?` | `` |  |\n| Affix | Target | `string?` | `` |  |\n| Affix | OnChange | `EventCallback<bool>` | `` |  |\n| Affix | Class | `string?` | `` |  |\n| Affix | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- `ChildContent` (Affix) — RenderFragment slot\n\n## Events\n- `OnChange` (`EventCallback<bool>`)\n\n## Sub-components\n- (none)\n\n## Cascading values it expects\n- (none)\n\n## Services it injects\n- `ComponentInteropService` ()\n\n## Keyboard\n—\n\n## Example\n```razor\n<Affix />\n```\n\n## CSS variables\n`--color-foreground`\n\n## Files\n- `UI/Affix/Affix.razor`\n"
}