@page "/components/data-table"

<PageTitle>Data Table — Lumeo</PageTitle>

<PageHeader Title="Data Table" Description="A powerful table component with templated headers, rows, loading states, and empty states." />

<div class="mt-10 space-y-3">
    <Heading Id="when-to-use" Level="2" Class="scroll-mt-20">When to Use</Heading>
    <ul class="list-disc list-inside space-y-1 text-muted-foreground text-sm">
        <li>Displaying sortable and filterable datasets with column headers</li>
        <li>Row selection for bulk actions like delete, export, or status changes</li>
        <li>Paginated lists of records such as users, orders, or transactions</li>
    </ul>
</div>

<Stack Gap="8" Class="mt-8">
    <ComponentDemo Title="Default" Code="@_defaultCode">
        <DataTable Items="_payments" Context="payment">
            <HeaderTemplate>
                <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Status</th>
                <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Email</th>
                <th class="h-10 px-4 text-right align-middle font-medium text-muted-foreground">Amount</th>
            </HeaderTemplate>
            <RowTemplate>
                <td class="p-4 align-middle">
                    <Badge Variant="@(payment.Status == "Success" ? Badge.BadgeVariant.Success : payment.Status == "Pending" ? Badge.BadgeVariant.Warning : Badge.BadgeVariant.Destructive)">
                        @payment.Status
                    </Badge>
                </td>
                <td class="p-4 align-middle text-foreground">@payment.Email</td>
                <td class="p-4 align-middle text-right text-foreground">$@payment.Amount.ToString("N2")</td>
            </RowTemplate>
        </DataTable>
    </ComponentDemo>

    <ComponentDemo Title="Loading State" Code="@_loadingCode">
        <DataTable Items="Array.Empty<Payment>()" TItem="Payment" IsLoading="true" SkeletonRows="3">
            <HeaderTemplate>
                <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Status</th>
                <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Email</th>
                <th class="h-10 px-4 text-right align-middle font-medium text-muted-foreground">Amount</th>
            </HeaderTemplate>
            <LoadingTemplate>
                <td class="p-4"><Skeleton Class="h-4 w-16" /></td>
                <td class="p-4"><Skeleton Class="h-4 w-40" /></td>
                <td class="p-4"><Skeleton Class="h-4 w-20 ml-auto" /></td>
            </LoadingTemplate>
            <RowTemplate>
                <td></td><td></td><td></td>
            </RowTemplate>
        </DataTable>
    </ComponentDemo>

    <ComponentDemo Title="Empty State" Code="@_emptyCode">
        <DataTable Items="Array.Empty<Payment>()" TItem="Payment">
            <HeaderTemplate>
                <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Status</th>
                <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Email</th>
                <th class="h-10 px-4 text-right align-middle font-medium text-muted-foreground">Amount</th>
            </HeaderTemplate>
            <EmptyTemplate>
                <EmptyState Title="No payments found" Description="There are no payments to display yet." />
            </EmptyTemplate>
            <RowTemplate>
                <td></td><td></td><td></td>
            </RowTemplate>
        </DataTable>
    </ComponentDemo>

    <ComponentDemo Title="Sortable Columns" Code="@_sortableCode">
        <DataTable Items="@GetSortedData()" TItem="SortableItem">
            <HeaderTemplate>
                <DataTableSortableHeader Column="name" SortColumn="@_sortColumn" SortDirection="@_sortDir" OnSort="@HandleSort">Name</DataTableSortableHeader>
                <DataTableSortableHeader Column="email" SortColumn="@_sortColumn" SortDirection="@_sortDir" OnSort="@HandleSort">Email</DataTableSortableHeader>
                <DataTableSortableHeader Column="role" SortColumn="@_sortColumn" SortDirection="@_sortDir" OnSort="@HandleSort">Role</DataTableSortableHeader>
            </HeaderTemplate>
            <RowTemplate>
                <td class="p-4 align-middle font-medium text-foreground">@context.Name</td>
                <td class="p-4 align-middle text-foreground">@context.Email</td>
                <td class="p-4 align-middle text-foreground">@context.Role</td>
            </RowTemplate>
        </DataTable>
    </ComponentDemo>

    <ComponentDemo Title="Row Selection" Code="@_selectionCode">
        <Stack Gap="2">
            <DataTable Items="_selectableData" TItem="SortableItem" Selectable="true" SelectedItems="@_selectedItems" SelectedItemsChanged="@(v => _selectedItems = v)">
                <HeaderTemplate>
                    <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Name</th>
                    <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Email</th>
                    <th class="h-10 px-4 text-left align-middle font-medium text-muted-foreground">Role</th>
                </HeaderTemplate>
                <RowTemplate>
                    <td class="p-4 align-middle font-medium text-foreground">@context.Name</td>
                    <td class="p-4 align-middle text-foreground">@context.Email</td>
                    <td class="p-4 align-middle text-foreground">@context.Role</td>
                </RowTemplate>
            </DataTable>
            <Lumeo.Text Class="text-sm text-muted-foreground">@_selectedItems.Count of @_selectableData.Count row(s) selected</Lumeo.Text>
        </Stack>
    </ComponentDemo>
</Stack>

<div class="mt-16">
    <Heading Id="api-reference" Level="2" Class="scroll-mt-20">API Reference</Heading>

    <Heading Id="datatable" Level="3" Class="mt-8 scroll-mt-20">DataTable&lt;TItem&gt;</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">Items</TableCell><TableCell Class="font-mono text-xs">IEnumerable&lt;TItem&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>The data source for table rows.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">HeaderTemplate</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Template for the table header row (th elements).</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">RowTemplate</TableCell><TableCell Class="font-mono text-xs">RenderFragment&lt;TItem&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Template for each data row. Receives the item as context.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">LoadingTemplate</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Template for skeleton loading rows shown when IsLoading is true.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">EmptyTemplate</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Template shown when Items is null or empty.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">IsLoading</TableCell><TableCell Class="font-mono text-xs">bool</TableCell><TableCell Class="font-mono text-xs">false</TableCell><TableCell>Show loading skeleton rows instead of data.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SkeletonRows</TableCell><TableCell Class="font-mono text-xs">int</TableCell><TableCell Class="font-mono text-xs">5</TableCell><TableCell>Number of skeleton rows to display when loading.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SortColumn</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>The currently sorted column key. Use with @@bind-SortColumn.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SortColumnChanged</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;string?&gt;</TableCell><TableCell Class="font-mono text-xs">-</TableCell><TableCell>Callback when the sort column changes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SortDir</TableCell><TableCell Class="font-mono text-xs">SortDirection</TableCell><TableCell Class="font-mono text-xs">Ascending</TableCell><TableCell>The current sort direction. Values: None, Ascending, Descending.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SortDirChanged</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;SortDirection&gt;</TableCell><TableCell Class="font-mono text-xs">-</TableCell><TableCell>Callback when the sort direction changes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">OnSort</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;(string, SortDirection)&gt;</TableCell><TableCell Class="font-mono text-xs">-</TableCell><TableCell>Callback with column key and new direction when a sortable header is clicked.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Selectable</TableCell><TableCell Class="font-mono text-xs">bool</TableCell><TableCell Class="font-mono text-xs">false</TableCell><TableCell>When true, adds a checkbox column for row selection.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SelectedItems</TableCell><TableCell Class="font-mono text-xs">HashSet&lt;TItem&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>The set of currently selected items. Use with @@bind-SelectedItems.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SelectedItemsChanged</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;HashSet&lt;TItem&gt;&gt;</TableCell><TableCell Class="font-mono text-xs">-</TableCell><TableCell>Callback when the selected items set changes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Virtualize</TableCell><TableCell Class="font-mono text-xs">bool</TableCell><TableCell Class="font-mono text-xs">false</TableCell><TableCell>Enables virtualized rendering for large datasets.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">ItemSize</TableCell><TableCell Class="font-mono text-xs">float</TableCell><TableCell Class="font-mono text-xs">48</TableCell><TableCell>Estimated height (px) of each row, used when Virtualize is true.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes for the table element.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>

    <Heading Id="datatablesortableheader" Level="3" Class="mt-8 scroll-mt-20">DataTableSortableHeader</Heading>
    <div class="overflow-x-auto mt-4">
        <Table>
            <TableHeader>
                <TableRow>
                    <TableHead Class="w-[180px]">Prop</TableHead>
                    <TableHead Class="w-[180px]">Type</TableHead>
                    <TableHead Class="w-[120px]">Default</TableHead>
                    <TableHead>Description</TableHead>
                </TableRow>
            </TableHeader>
            <TableBody>
                <TableRow><TableCell Class="font-mono text-xs">ChildContent</TableCell><TableCell Class="font-mono text-xs">RenderFragment?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>The header label content.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Column</TableCell><TableCell Class="font-mono text-xs">string</TableCell><TableCell Class="font-mono text-xs">""</TableCell><TableCell>The column key this header controls sorting for. Required.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SortColumn</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>The currently active sort column, used to highlight this header.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">SortDirection</TableCell><TableCell Class="font-mono text-xs">DataTable&lt;object&gt;.SortDirection</TableCell><TableCell Class="font-mono text-xs">None</TableCell><TableCell>The current sort direction, used to render the appropriate arrow icon.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">OnSort</TableCell><TableCell Class="font-mono text-xs">EventCallback&lt;(string, SortDirection)&gt;</TableCell><TableCell Class="font-mono text-xs">-</TableCell><TableCell>Callback invoked with the column key and toggled direction when clicked.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">Class</TableCell><TableCell Class="font-mono text-xs">string?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional CSS classes.</TableCell></TableRow>
                <TableRow><TableCell Class="font-mono text-xs">AdditionalAttributes</TableCell><TableCell Class="font-mono text-xs">Dictionary&lt;string, object&gt;?</TableCell><TableCell Class="font-mono text-xs">null</TableCell><TableCell>Additional HTML attributes.</TableCell></TableRow>
            </TableBody>
        </Table>
    </div>
</div>

<div class="mt-12">
    <Heading Id="related" Level="2" Class="scroll-mt-20">Related Components</Heading>
    <ul class="mt-4 space-y-2 text-sm">
        <li><a href="/components/table" class="text-primary hover:underline">Table</a> — For simple static tables without sorting, selection, or loading states</li>
        <li><a href="/components/pagination" class="text-primary hover:underline">Pagination</a> — For navigating between pages of data in a table</li>
    </ul>
</div>

@code {
    private record Payment(string Status, string Email, decimal Amount);
    private record SortableItem(string Name, string Email, string Role);

    private readonly Payment[] _payments =
    [
        new("Success", "ken@example.com", 316.00m),
        new("Success", "abe@example.com", 242.00m),
        new("Pending", "monserrat@example.com", 837.00m),
        new("Failed", "silas@example.com", 874.00m),
        new("Success", "carmella@example.com", 721.00m),
    ];

    private List<SortableItem> _sortableData =
    [
        new("Alice Johnson", "alice@example.com", "Admin"),
        new("Bob Smith", "bob@example.com", "User"),
        new("Carol White", "carol@example.com", "Editor"),
        new("Dave Brown", "dave@example.com", "User"),
    ];

    private List<SortableItem> _selectableData =
    [
        new("Alice Johnson", "alice@example.com", "Admin"),
        new("Bob Smith", "bob@example.com", "User"),
        new("Carol White", "carol@example.com", "Editor"),
        new("Dave Brown", "dave@example.com", "User"),
    ];

    private string? _sortColumn;
    private DataTable<object>.SortDirection _sortDir = DataTable<object>.SortDirection.None;
    private HashSet<SortableItem> _selectedItems = new();

    private void HandleSort((string Column, DataTable<object>.SortDirection Direction) sort)
    {
        _sortColumn = sort.Column;
        _sortDir = sort.Direction;
    }

    private IEnumerable<SortableItem> GetSortedData()
    {
        if (_sortColumn is null || _sortDir == DataTable<object>.SortDirection.None) return _sortableData;
        return _sortDir == DataTable<object>.SortDirection.Ascending
            ? _sortColumn switch
            {
                "email" => _sortableData.OrderBy(x => x.Email),
                "role"  => _sortableData.OrderBy(x => x.Role),
                _       => _sortableData.OrderBy(x => x.Name),
            }
            : _sortColumn switch
            {
                "email" => _sortableData.OrderByDescending(x => x.Email),
                "role"  => _sortableData.OrderByDescending(x => x.Role),
                _       => _sortableData.OrderByDescending(x => x.Name),
            };
    }

    private string _defaultCode = @"<DataTable Items=""_payments"" Context=""payment"">
    <HeaderTemplate>
        <th class=""h-10 px-4 text-left font-medium text-muted-foreground"">Status</th>
        <th class=""h-10 px-4 text-left font-medium text-muted-foreground"">Email</th>
        <th class=""h-10 px-4 text-right font-medium text-muted-foreground"">Amount</th>
    </HeaderTemplate>
    <RowTemplate>
        <td class=""p-4"">@payment.Status</td>
        <td class=""p-4"">@payment.Email</td>
        <td class=""p-4 text-right"">$@payment.Amount</td>
    </RowTemplate>
</DataTable>";

    private string _loadingCode = @"<DataTable Items=""Array.Empty<Item>()"" TItem=""Item"" IsLoading=""true"" SkeletonRows=""3"">
    <HeaderTemplate>...</HeaderTemplate>
    <LoadingTemplate>
        <td class=""p-4""><Skeleton Class=""h-4 w-16"" /></td>
    </LoadingTemplate>
    <RowTemplate>...</RowTemplate>
</DataTable>";

    private string _emptyCode = @"<DataTable Items=""Array.Empty<Item>()"" TItem=""Item"">
    <HeaderTemplate>...</HeaderTemplate>
    <EmptyTemplate>
        <EmptyState Title=""No data"" Description=""Nothing to display."" />
    </EmptyTemplate>
    <RowTemplate>...</RowTemplate>
</DataTable>";

    private string _sortableCode = @"<DataTable Items=""@GetSortedData()"" TItem=""Item"" SortColumn=""@_sortColumn"" SortDir=""@_sortDir"" OnSort=""@HandleSort"">
    <HeaderTemplate>
        <DataTableSortableHeader Column=""name"" SortColumn=""@_sortColumn"" SortDirection=""@_sortDir"" OnSort=""@HandleSort"">Name</DataTableSortableHeader>
        <DataTableSortableHeader Column=""email"" SortColumn=""@_sortColumn"" SortDirection=""@_sortDir"" OnSort=""@HandleSort"">Email</DataTableSortableHeader>
        <DataTableSortableHeader Column=""role"" SortColumn=""@_sortColumn"" SortDirection=""@_sortDir"" OnSort=""@HandleSort"">Role</DataTableSortableHeader>
    </HeaderTemplate>
    <RowTemplate>
        <td class=""p-4"">@context.Name</td>
        <td class=""p-4"">@context.Email</td>
        <td class=""p-4"">@context.Role</td>
    </RowTemplate>
</DataTable>

@code {
    private string? _sortColumn;
    private DataTable<Item>.SortDirection _sortDir = DataTable<Item>.SortDirection.None;

    private void HandleSort((string Column, DataTable<Item>.SortDirection Direction) sort)
    {
        _sortColumn = sort.Column;
        _sortDir = sort.Direction;
    }
}";

    private string _selectionCode = @"<DataTable Items=""_data"" TItem=""Item"" Selectable=""true"" @bind-SelectedItems=""_selectedItems"">
    <HeaderTemplate>
        <TableRow>
            <TableHead>Name</TableHead>
            <TableHead>Email</TableHead>
            <TableHead>Role</TableHead>
        </TableRow>
    </HeaderTemplate>
    <RowTemplate>
        <TableCell Class=""font-medium"">@context.Name</TableCell>
        <TableCell>@context.Email</TableCell>
        <TableCell>@context.Role</TableCell>
    </RowTemplate>
</DataTable>
<p class=""text-sm text-muted-foreground"">@_selectedItems.Count of @_data.Count row(s) selected</p>

@code {
    private HashSet<Item> _selectedItems = new();
}";
}
