{
  "name": "DataTable",
  "category": "Data Display",
  "subcategory": "Tables",
  "description": "Table with sorting, pagination, and row selection built in.",
  "thumbnail": "/preview-cards/data-table.png",
  "hasDocsPage": true,
  "nugetPackage": "Lumeo.DataGrid",
  "files": [
    "UI/DataTable/DataTable.razor",
    "UI/DataTable/DataTableSortableHeader.razor"
  ],
  "dependencies": [
    "checkbox"
  ],
  "packageDependencies": [
    "Blazicons.Lucide"
  ],
  "cssVars": [
    "--color-accent",
    "--color-accent-foreground",
    "--color-border",
    "--color-muted",
    "--color-muted-foreground",
    "--radius"
  ],
  "api": {
    "name": "DataTable",
    "category": "Data Display",
    "subcategory": "Tables",
    "description": "Table with sorting, pagination, and row selection built in.",
    "nugetPackage": "Lumeo.DataGrid",
    "files": [
      "UI/DataTable/DataTable.razor",
      "UI/DataTable/DataTableSortableHeader.razor"
    ],
    "namespace": "Lumeo",
    "inheritsFrom": null,
    "implements": [],
    "parameters": [
      {
        "name": "Items",
        "type": "IEnumerable<TItem>?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "HeaderTemplate",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "RowTemplate",
        "type": "RenderFragment<TItem>?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "LoadingTemplate",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "EmptyTemplate",
        "type": "RenderFragment?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "IsLoading",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "SkeletonRows",
        "type": "int",
        "default": "5",
        "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
      },
      {
        "name": "SortColumn",
        "type": "string?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "SortColumnChanged",
        "type": "EventCallback<string?>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "SortDir",
        "type": "SortDirection",
        "default": "SortDirection.Ascending",
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "SortDirChanged",
        "type": "EventCallback<SortDirection>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "OnSort",
        "type": "EventCallback<(string Column, SortDirection Direction)>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Selectable",
        "type": "bool",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "SelectedItems",
        "type": "HashSet<TItem>?",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "SelectedItemsChanged",
        "type": "EventCallback<HashSet<TItem>>",
        "default": null,
        "description": null,
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "Virtualize",
        "type": "bool",
        "default": null,
        "description": "Virtualize the row list using Blazor's &lt;Virtualize&gt; — only renders rows in the viewport.",
        "isCascading": false,
        "captureUnmatched": false
      },
      {
        "name": "ItemSize",
        "type": "float",
        "default": "48",
        "description": "Estimated row height in pixels used by the virtualizer (default 41). Only relevant when Virtualize is true.",
        "isCascading": false,
        "captureUnmatched": false
      }
    ],
    "events": [
      {
        "name": "SortColumnChanged",
        "type": "EventCallback<string?>",
        "description": null
      },
      {
        "name": "SortDirChanged",
        "type": "EventCallback<SortDirection>",
        "description": null
      },
      {
        "name": "OnSort",
        "type": "EventCallback<(string Column, SortDirection Direction)>",
        "description": null
      },
      {
        "name": "SelectedItemsChanged",
        "type": "EventCallback<HashSet<TItem>>",
        "description": null
      }
    ],
    "enums": [
      {
        "name": "SortDirection",
        "values": [
          "None",
          "Ascending",
          "Descending"
        ],
        "description": null
      }
    ],
    "records": [],
    "cssVars": [
      "--color-accent",
      "--color-accent-foreground",
      "--color-border",
      "--color-muted",
      "--color-muted-foreground",
      "--radius"
    ],
    "examples": [
      {
        "title": "Default",
        "code": "<DataTable Items=\"_payments\" Context=\"payment\">\n    <HeaderTemplate>\n        <th class=\"h-10 px-4 text-left font-medium text-muted-foreground\">Status</th>\n        <th class=\"h-10 px-4 text-left font-medium text-muted-foreground\">Email</th>\n        <th class=\"h-10 px-4 text-right font-medium text-muted-foreground\">Amount</th>\n    </HeaderTemplate>\n    <RowTemplate>\n        <td class=\"p-4\">@payment.Status</td>\n        <td class=\"p-4\">@payment.Email</td>\n        <td class=\"p-4 text-right\">$@payment.Amount</td>\n    </RowTemplate>\n</DataTable>"
      },
      {
        "title": "Loading State",
        "code": "<DataTable Items=\"Array.Empty<Item>()\" TItem=\"Item\" IsLoading=\"true\" SkeletonRows=\"3\">\n    <HeaderTemplate>...</HeaderTemplate>\n    <LoadingTemplate>\n        <td class=\"p-4\"><Skeleton Class=\"h-4 w-16\" /></td>\n    </LoadingTemplate>\n    <RowTemplate>...</RowTemplate>\n</DataTable>"
      },
      {
        "title": "Empty State",
        "code": "<DataTable Items=\"Array.Empty<Item>()\" TItem=\"Item\">\n    <HeaderTemplate>...</HeaderTemplate>\n    <EmptyTemplate>\n        <EmptyState Title=\"No data\" Description=\"Nothing to display.\" />\n    </EmptyTemplate>\n    <RowTemplate>...</RowTemplate>\n</DataTable>"
      },
      {
        "title": "Sortable Columns",
        "code": "<DataTable Items=\"@GetSortedData()\" TItem=\"Item\" SortColumn=\"@_sortColumn\" SortDir=\"@_sortDir\" OnSort=\"@HandleSort\">\n    <HeaderTemplate>\n        <DataTableSortableHeader Column=\"name\" SortColumn=\"@_sortColumn\" SortDirection=\"@_sortDir\" OnSort=\"@HandleSort\">Name</DataTableSortableHeader>\n        <DataTableSortableHeader Column=\"email\" SortColumn=\"@_sortColumn\" SortDirection=\"@_sortDir\" OnSort=\"@HandleSort\">Email</DataTableSortableHeader>\n        <DataTableSortableHeader Column=\"role\" SortColumn=\"@_sortColumn\" SortDirection=\"@_sortDir\" OnSort=\"@HandleSort\">Role</DataTableSortableHeader>\n    </HeaderTemplate>\n    <RowTemplate>\n        <td class=\"p-4\">@context.Name</td>\n        <td class=\"p-4\">@context.Email</td>\n        <td class=\"p-4\">@context.Role</td>\n    </RowTemplate>\n</DataTable>\n\n@code {\n    private string? _sortColumn;\n    private DataTable<Item>.SortDirection _sortDir = DataTable<Item>.SortDirection.None;\n\n    private void HandleSort((string Column, DataTable<Item>.SortDirection Direction) sort)\n    {\n        _sortColumn = sort.Column;\n        _sortDir = sort.Direction;\n    }\n}"
      }
    ],
    "subComponents": {
      "DataTableSortableHeader": {
        "componentName": "DataTableSortableHeader",
        "fileName": "DataTableSortableHeader.razor",
        "namespace": "Lumeo",
        "inheritsFrom": null,
        "implements": [],
        "parameters": [
          {
            "name": "ChildContent",
            "type": "RenderFragment?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "Column",
            "type": "string",
            "default": "\"\"",
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "SortColumn",
            "type": "string?",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "SortDirection",
            "type": "DataTable<object>.SortDirection",
            "default": null,
            "description": null,
            "isCascading": false,
            "captureUnmatched": false
          },
          {
            "name": "OnSort",
            "type": "EventCallback<(string Column, DataTable<object>.SortDirection Direction)>",
            "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": "OnSort",
            "type": "EventCallback<(string Column, DataTable<object>.SortDirection Direction)>",
            "description": null
          }
        ],
        "enums": [],
        "records": [],
        "parseFailed": false,
        "parseError": null
      }
    },
    "parseFailed": false,
    "parseError": null
  },
  "$schema": "https://lumeo.nativ.sh/registry-component-schema.json",
  "key": "data-table",
  "docsUrl": "https://lumeo.nativ.sh/components/data-table",
  "sourceUrl": [
    {
      "file": "UI/DataTable/DataTable.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo.DataGrid/UI/DataTable/DataTable.razor"
    },
    {
      "file": "UI/DataTable/DataTableSortableHeader.razor",
      "url": "https://github.com/Brain2k-0005/Lumeo/tree/master/src/Lumeo.DataGrid/UI/DataTable/DataTableSortableHeader.razor"
    }
  ],
  "source": [
    {
      "path": "UI/DataTable/DataTable.razor",
      "content": "@namespace Lumeo\n@typeparam TItem\n\n<div class=\"relative w-full overflow-auto\" @attributes=\"AdditionalAttributes\">\n    <table class=\"@CssClass\">\n        <thead class=\"[&_tr]:border-b [&_tr]:border-border/40\">\n            <tr class=\"border-b border-border/40 transition-colors hover:bg-muted/50\">\n                @if (Selectable)\n                {\n                    <th class=\"h-10 w-10 px-2 text-left align-middle font-medium text-muted-foreground\">\n                        <Checkbox Checked=\"@IsAllSelected\" IsIndeterminate=\"@IsSomeSelected\" CheckedChanged=\"@ToggleSelectAll\" />\n                    </th>\n                }\n                @HeaderTemplate\n            </tr>\n        </thead>\n        <tbody class=\"[&_tr:last-child]:border-0\">\n            @if (IsLoading)\n            {\n                @for (var i = 0; i < SkeletonRows; i++)\n                {\n                    <tr class=\"border-b border-border/40\">\n                        @LoadingTemplate\n                    </tr>\n                }\n            }\n            else if (Items is null || !Items.Any())\n            {\n                <tr>\n                    <td colspan=\"100\" class=\"p-8\">\n                        @if (EmptyTemplate is not null)\n                        {\n                            @EmptyTemplate\n                        }\n                        else\n                        {\n                            <div class=\"flex flex-col items-center justify-center py-8 text-center\">\n                                <p class=\"text-sm text-muted-foreground\">No results.</p>\n                            </div>\n                        }\n                    </td>\n                </tr>\n            }\n            else if (Virtualize)\n            {\n                <Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize Items=\"@_itemsList\" Context=\"item\" SpacerElement=\"tr\" ItemSize=\"@(ItemSize > 0 ? ItemSize : 41f)\">\n                    <tr class=\"border-b border-border/40 transition-colors hover:bg-muted/50\">\n                        @if (Selectable)\n                        {\n                            <td class=\"w-10 px-2 py-2 align-middle\">\n                                <Checkbox Checked=\"@(SelectedItems?.Contains(item) == true)\" CheckedChanged=\"@(c => ToggleItem(item, c))\" />\n                            </td>\n                        }\n                        @RowTemplate!(item)\n                    </tr>\n                </Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize>\n            }\n            else\n            {\n                @foreach (var item in _itemsList)\n                {\n                    <tr @key=\"item\" class=\"border-b border-border/40 transition-colors hover:bg-muted/50\">\n                        @if (Selectable)\n                        {\n                            <td class=\"w-10 px-2 py-2 align-middle\">\n                                <Checkbox Checked=\"@(SelectedItems?.Contains(item) == true)\" CheckedChanged=\"@(c => ToggleItem(item, c))\" />\n                            </td>\n                        }\n                        @RowTemplate!(item)\n                    </tr>\n                }\n            }\n        </tbody>\n    </table>\n</div>\n\n@code {\n    [Parameter] public IEnumerable<TItem>? Items { get; set; }\n    [Parameter] public RenderFragment? HeaderTemplate { get; set; }\n    [Parameter] public RenderFragment<TItem>? RowTemplate { get; set; }\n    [Parameter] public RenderFragment? LoadingTemplate { get; set; }\n    [Parameter] public RenderFragment? EmptyTemplate { get; set; }\n    [Parameter] public bool IsLoading { get; set; }\n    [Parameter] public int SkeletonRows { get; set; } = 5;\n    [Parameter] public string? Class { get; set; }\n    [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object>? AdditionalAttributes { get; set; }\n\n    // Sorting\n    [Parameter] public string? SortColumn { get; set; }\n    [Parameter] public EventCallback<string?> SortColumnChanged { get; set; }\n    [Parameter] public SortDirection SortDir { get; set; } = SortDirection.Ascending;\n    [Parameter] public EventCallback<SortDirection> SortDirChanged { get; set; }\n    [Parameter] public EventCallback<(string Column, SortDirection Direction)> OnSort { get; set; }\n\n    // Selection\n    [Parameter] public bool Selectable { get; set; }\n    [Parameter] public HashSet<TItem>? SelectedItems { get; set; }\n    [Parameter] public EventCallback<HashSet<TItem>> SelectedItemsChanged { get; set; }\n\n    // Virtualization\n    /// <summary>Virtualize the row list using Blazor's &lt;Virtualize&gt; — only renders rows in the viewport.</summary>\n    [Parameter] public bool Virtualize { get; set; }\n    /// <summary>Estimated row height in pixels used by the virtualizer (default 41). Only relevant when <see cref=\"Virtualize\"/> is true.</summary>\n    [Parameter] public float ItemSize { get; set; } = 48;\n\n    private string CssClass => $\"w-full caption-bottom text-sm {Class}\".Trim();\n\n    // Cached per-render — recomputed in OnParametersSet to avoid repeated LINQ on every render pass.\n    private List<TItem> _itemsList = [];\n    private bool _isAllSelected;\n    private bool _isSomeSelected;\n\n    private bool IsAllSelected => _isAllSelected;\n    private bool IsSomeSelected => _isSomeSelected;\n\n    protected override void OnParametersSet()\n    {\n        _itemsList = Items?.ToList() ?? [];\n        _isAllSelected = _itemsList.Count > 0 && SelectedItems is not null && _itemsList.All(i => SelectedItems.Contains(i));\n        _isSomeSelected = SelectedItems is not null && SelectedItems.Count > 0 && !_isAllSelected;\n    }\n\n    private async Task ToggleSelectAll(bool select)\n    {\n        if (Items is null) return;\n        SelectedItems ??= [];\n        if (select)\n        {\n            foreach (var item in Items) SelectedItems.Add(item);\n        }\n        else\n        {\n            SelectedItems.Clear();\n        }\n        RefreshSelectionCache();\n        await SelectedItemsChanged.InvokeAsync(SelectedItems);\n    }\n\n    private async Task ToggleItem(TItem item, bool selected)\n    {\n        SelectedItems ??= [];\n        if (selected) SelectedItems.Add(item);\n        else SelectedItems.Remove(item);\n        RefreshSelectionCache();\n        await SelectedItemsChanged.InvokeAsync(SelectedItems);\n    }\n\n    private void RefreshSelectionCache()\n    {\n        _isAllSelected = _itemsList.Count > 0 && SelectedItems is not null && _itemsList.All(i => SelectedItems.Contains(i));\n        _isSomeSelected = SelectedItems is not null && SelectedItems.Count > 0 && !_isAllSelected;\n    }\n\n    public enum SortDirection { None, Ascending, Descending }\n}\n"
    },
    {
      "path": "UI/DataTable/DataTableSortableHeader.razor",
      "content": "@namespace Lumeo\n\n<th class=\"@CssClass\" @attributes=\"AdditionalAttributes\">\n    <button type=\"button\" class=\"inline-flex items-center gap-1 -ml-3 h-8 px-3 rounded-md hover:bg-accent hover:text-accent-foreground\" @onclick=\"HandleSort\">\n        @ChildContent\n        @if (SortColumn == Column)\n        {\n            @if (SortDirection == DataTable<object>.SortDirection.Ascending)\n            {\n                <Blazicon Svg=\"Lucide.ArrowUp\" class=\"h-3.5 w-3.5\" />\n            }\n            else if (SortDirection == DataTable<object>.SortDirection.Descending)\n            {\n                <Blazicon Svg=\"Lucide.ArrowDown\" class=\"h-3.5 w-3.5\" />\n            }\n            else\n            {\n                <Blazicon Svg=\"Lucide.ArrowUpDown\" class=\"h-3.5 w-3.5 opacity-50\" />\n            }\n        }\n        else\n        {\n            <Blazicon Svg=\"Lucide.ArrowUpDown\" class=\"h-3.5 w-3.5 opacity-50\" />\n        }\n    </button>\n</th>\n\n@code {\n    [Parameter] public RenderFragment? ChildContent { get; set; }\n    [Parameter, EditorRequired] public string Column { get; set; } = \"\";\n    [Parameter] public string? SortColumn { get; set; }\n    [Parameter] public DataTable<object>.SortDirection SortDirection { get; set; }\n    [Parameter] public EventCallback<(string Column, DataTable<object>.SortDirection Direction)> OnSort { 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 => $\"h-10 px-2 text-left align-middle font-medium text-muted-foreground {Class}\".Trim();\n\n    private async Task HandleSort()\n    {\n        var newDirection = SortColumn == Column\n            ? SortDirection switch\n            {\n                DataTable<object>.SortDirection.Ascending => DataTable<object>.SortDirection.Descending,\n                DataTable<object>.SortDirection.Descending => DataTable<object>.SortDirection.None,\n                _ => DataTable<object>.SortDirection.Ascending\n            }\n            : DataTable<object>.SortDirection.Ascending;\n\n        await OnSort.InvokeAsync((Column, newDirection));\n    }\n}\n"
    }
  ],
  "slots": [
    {
      "name": "HeaderTemplate",
      "owner": "DataTable",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "RowTemplate",
      "owner": "DataTable",
      "type": "RenderFragment<TItem>?",
      "description": null
    },
    {
      "name": "LoadingTemplate",
      "owner": "DataTable",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "EmptyTemplate",
      "owner": "DataTable",
      "type": "RenderFragment?",
      "description": null
    },
    {
      "name": "ChildContent",
      "owner": "DataTableSortableHeader",
      "type": "RenderFragment?",
      "description": null
    }
  ],
  "serviceDependencies": [],
  "cascadingDependencies": [],
  "relatedComponents": [
    {
      "name": "DataTableSortableHeader",
      "reason": "sub-component"
    },
    {
      "name": "Checkbox",
      "reason": "used internally"
    }
  ],
  "keyboardInteractions": [],
  "tests": [
    "tests/Lumeo.Tests/Components/DataTable/DataTableTests.cs",
    "tests/Lumeo.Tests/Contract/ComponentContractTests.cs"
  ],
  "mdSummary": "# DataTable\n\nTable with sorting, pagination, and row selection built in.\n\n**Package:** `Lumeo.DataGrid` · **Category:** Data Display/Tables\n**Docs:** https://lumeo.nativ.sh/components/data-table\n\n## Parameters\n| Owner | Name | Type | Default | Description |\n|---|---|---|---|---|\n| DataTable | Items | `IEnumerable<TItem>?` | `` |  |\n| DataTable | HeaderTemplate | `RenderFragment?` | `` |  |\n| DataTable | RowTemplate | `RenderFragment<TItem>?` | `` |  |\n| DataTable | LoadingTemplate | `RenderFragment?` | `` |  |\n| DataTable | EmptyTemplate | `RenderFragment?` | `` |  |\n| DataTable | IsLoading | `bool` | `` |  |\n| DataTable | SkeletonRows | `int` | `5` |  |\n| DataTable | Class | `string?` | `` |  |\n| DataTable | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n| DataTable | SortColumn | `string?` | `` |  |\n| DataTable | SortColumnChanged | `EventCallback<string?>` | `` |  |\n| DataTable | SortDir | `SortDirection` | `SortDirection.Ascending` |  |\n| DataTable | SortDirChanged | `EventCallback<SortDirection>` | `` |  |\n| DataTable | OnSort | `EventCallback<(string Column, SortDirection Direction)>` | `` |  |\n| DataTable | Selectable | `bool` | `` |  |\n| DataTable | SelectedItems | `HashSet<TItem>?` | `` |  |\n| DataTable | SelectedItemsChanged | `EventCallback<HashSet<TItem>>` | `` |  |\n| DataTable | Virtualize | `bool` | `` | Virtualize the row list using Blazor's &lt;Virtualize&gt; — only renders rows in the viewport. |\n| DataTable | ItemSize | `float` | `48` | Estimated row height in pixels used by the virtualizer (default 41). Only relevant when Virtualize is true. |\n| DataTableSortableHeader | ChildContent | `RenderFragment?` | `` |  |\n| DataTableSortableHeader | Column | `string` | `\"\"` |  |\n| DataTableSortableHeader | SortColumn | `string?` | `` |  |\n| DataTableSortableHeader | SortDirection | `DataTable<object>.SortDirection` | `` |  |\n| DataTableSortableHeader | OnSort | `EventCallback<(string Column, DataTable<object>.SortDirection Direction)>` | `` |  |\n| DataTableSortableHeader | Class | `string?` | `` |  |\n| DataTableSortableHeader | AdditionalAttributes | `Dictionary<string, object>?` | `` |  |\n\n## Slots\n- `HeaderTemplate` (DataTable) — RenderFragment slot\n- `RowTemplate` (DataTable) — RenderFragment slot\n- `LoadingTemplate` (DataTable) — RenderFragment slot\n- `EmptyTemplate` (DataTable) — RenderFragment slot\n- `ChildContent` (DataTableSortableHeader) — RenderFragment slot\n\n## Events\n- `SortColumnChanged` (`EventCallback<string?>`)\n- `SortDirChanged` (`EventCallback<SortDirection>`)\n- `OnSort` (`EventCallback<(string Column, SortDirection Direction)>`)\n- `SelectedItemsChanged` (`EventCallback<HashSet<TItem>>`)\n\n## Sub-components\n- `DataTableSortableHeader`\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<DataTable />\n```\n\n## CSS variables\n`--color-accent`, `--color-accent-foreground`, `--color-border`, `--color-muted`, `--color-muted-foreground`, `--radius`\n\n## Files\n- `UI/DataTable/DataTable.razor`\n- `UI/DataTable/DataTableSortableHeader.razor`\n"
}