mirror of
https://gitee.com/ant-design-blazor/ant-design-blazor.git
synced 2024-12-02 12:07:44 +08:00
f3e0ec96e1
Co-authored-by: thirking <king2381955@sina.com>
329 lines
15 KiB
C#
329 lines
15 KiB
C#
@namespace AntDesign
|
|
@inherits AntDomComponentBase
|
|
@using AntDesign.TableModels
|
|
@using AntDesign.Internal
|
|
@using AntDesign.Core.Component.ResizeObserver
|
|
|
|
@typeparam TItem
|
|
|
|
<div class="@_wrapperClassMapper.Class" @ref="Ref">
|
|
<Spin Spinning="Loading">
|
|
@if (!HidePagination && PaginationPosition.Contains("top"))
|
|
{
|
|
if (PaginationTemplate == null)
|
|
{
|
|
<Pagination Size="@(Size == TableSize.Default ? PaginationSize.Default : PaginationSize.Small)"
|
|
Class="@_paginationClass.Class"
|
|
Total="_total"
|
|
PageSize="PageSize"
|
|
Current="PageIndex"
|
|
OnChange="HandlePageChange" />
|
|
}
|
|
else
|
|
{
|
|
@PaginationTemplate((PageSize,PageIndex,_total,_paginationClass.Class, EventCallback.Factory.Create<PaginationEventArgs>(this, HandlePageChange)))
|
|
}
|
|
}
|
|
|
|
<CascadingValue Value="@this" TValue="ITable" IsFixed>
|
|
<CascadingValue Value=@typeof(TItem) Name="ItemType" IsFixed>
|
|
<CascadingValue Value="@ColumnContext" IsFixed>
|
|
<CascadingValue Name="IsInitialize" Value="true" IsFixed>
|
|
@if (_fieldModel is not null)
|
|
{
|
|
@ChildContent(_fieldModel)
|
|
}
|
|
</CascadingValue>
|
|
<div class="@ClassMapper.Class" @ref="_wrapperRef">
|
|
@if (TitleTemplate != null || Title != null)
|
|
{
|
|
<div class="ant-table-title">
|
|
@if (TitleTemplate != null)@TitleTemplate else @Title
|
|
</div>
|
|
}
|
|
<div class="ant-table-container">
|
|
@if (ScrollY != null)
|
|
{
|
|
<div class="ant-table-header" style="overflow: hidden;" @ref="_tableHeaderRef">
|
|
<table style="@TableLayoutStyle">
|
|
@colGroup(this, true)
|
|
@header()
|
|
</table>
|
|
</div>
|
|
<div class="ant-table-body" @ref="_tableBodyRef" style="@(ScrollX!=null?" overflow: auto scroll;":"overflow-y: scroll;") max-height: @((CssSizeLength)ScrollY); @(UseItemsProvider?$"min-height:{(CssSizeLength)ScrollY};":"") @(ScrollBarWidth == null ? "" : $"--scrollbar-width: {(CssSizeLength)_scrollBarWidth};")">
|
|
<table style="@(ScrollX!=null?$"width: {(CssSizeLength)ScrollX}; min-width: 100%;":"") @TableLayoutStyle" @ref="_tableRef">
|
|
@colGroup(this, false)
|
|
<tbody class="ant-table-tbody">
|
|
<tr aria-hidden="true" class="ant-table-measure-row" style="height: 0px; font-size: 0px;">
|
|
<CascadingValue Name="IsMeasure" Value="true" IsFixed>
|
|
@if (_fieldModel is not null)
|
|
{
|
|
@ChildContent(_fieldModel)
|
|
}
|
|
</CascadingValue>
|
|
</tr>
|
|
@body(_showItems)
|
|
</tbody>
|
|
@tfoot()
|
|
</table>
|
|
</div>
|
|
}
|
|
else if (ScrollX != null)
|
|
{
|
|
<div class="ant-table-content" @ref="_tableBodyRef" style="overflow: auto hidden; @(ScrollBarWidth == null ? "" : $"--scrollbar-width: {(CssSizeLength)_scrollBarWidth};")">
|
|
<table style="width: @((CssSizeLength)ScrollX); min-width: 100%; @TableLayoutStyle;" @ref="_tableRef">
|
|
@colGroup(this, true)
|
|
@header()
|
|
<tbody class="ant-table-tbody">
|
|
<tr aria-hidden="true" class="ant-table-measure-row" style="height: 0px; font-size: 0px;">
|
|
<CascadingValue Name="IsMeasure" Value="true" IsFixed>
|
|
@if (_fieldModel is not null)
|
|
{
|
|
@ChildContent(_fieldModel)
|
|
}
|
|
</CascadingValue>
|
|
</tr>
|
|
@body(_showItems)
|
|
</tbody>
|
|
@tfoot()
|
|
</table>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="ant-table-content">
|
|
<table style="@TableLayoutStyle;@(ScrollBarWidth == null ? "" : $"--scrollbar-width: {(CssSizeLength)_scrollBarWidth};")" @ref="_tableRef">
|
|
@colGroup(this, true)
|
|
@header()
|
|
<tbody class="ant-table-tbody">
|
|
@body(_showItems)
|
|
</tbody>
|
|
@tfoot()
|
|
</table>
|
|
</div>
|
|
}
|
|
</div>
|
|
@if (FooterTemplate != null || Footer != null)
|
|
{
|
|
<div class="ant-table-footer">
|
|
@if (FooterTemplate != null)@FooterTemplate else @Footer
|
|
</div>
|
|
}
|
|
</div>
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
@if (!HidePagination && PaginationPosition.Contains("bottom"))
|
|
{
|
|
if (PaginationTemplate == null)
|
|
{
|
|
<Pagination Size="@(Size == TableSize.Default ? PaginationSize.Default : PaginationSize.Small)"
|
|
Class="@_paginationClass.Class"
|
|
Total="_total"
|
|
PageSize="PageSize"
|
|
Current="PageIndex"
|
|
OnChange="HandlePageChange" />
|
|
}
|
|
else
|
|
{
|
|
@PaginationTemplate((PageSize,PageIndex,_total,_paginationClass.Class, EventCallback.Factory.Create<PaginationEventArgs>(this, HandlePageChange)))
|
|
}
|
|
}
|
|
</Spin>
|
|
</div>
|
|
|
|
@code
|
|
{
|
|
RenderFragment header()
|
|
{
|
|
var headerRowAttributes = OnHeaderRow?.Invoke();
|
|
return @<thead class="ant-table-thead">
|
|
<CascadingValue Name="IsHeader" Value="true" IsFixed>
|
|
<CascadingValue Value="headerRowAttributes" Name="AntDesign.TableRow.RowAttributes">
|
|
<CascadingValue Value="_hasFixRight" Name="AntDesign.TableRow.HasFixRight">
|
|
<CascadingValue Value="ScrollY" Name="AntDesign.TableRow.ScrollY">
|
|
@if (_fieldModel is not null)
|
|
{
|
|
@if (HeaderTemplate != null)
|
|
{
|
|
@HeaderTemplate(_fieldModel)
|
|
}
|
|
else
|
|
{
|
|
<TableRow>
|
|
@ChildContent(_fieldModel)
|
|
</TableRow>
|
|
}
|
|
}
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
</thead>;
|
|
}
|
|
|
|
static RenderFragment colGroup(Table<TItem> table, bool header)
|
|
{
|
|
var realSize = (CssSizeLength)((table as ITable).RealScrollBarSize);
|
|
return @<colgroup>
|
|
<CascadingValue Name="IsColGroup" Value="true" IsFixed>
|
|
@if (_fieldModel is not null)
|
|
{
|
|
@table.ChildContent(_fieldModel)
|
|
}
|
|
</CascadingValue>
|
|
@if (table.ScrollY != null && header)
|
|
{
|
|
<col style="width: @realSize; min-width: @realSize;" />
|
|
}
|
|
</colgroup>;
|
|
}
|
|
|
|
|
|
RenderFragment body(IEnumerable<TItem> showItems, RowData<TItem> parentRowData = null)
|
|
{
|
|
var level = (parentRowData?.Level + 1) ?? 0;
|
|
|
|
if (!_hasInitialized)
|
|
{
|
|
return builder => { };
|
|
}
|
|
#if NET5_0_OR_GREATER
|
|
if (UseItemsProvider&&!_isVirtualizeEmpty)
|
|
{
|
|
return @<Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize TItem="RowData<TItem>"
|
|
OverscanCount="10"
|
|
ItemsProvider="ItemsProvider"
|
|
ItemContent="bodyRow()">
|
|
<Placeholder>
|
|
<tr class="ant-table-row ant-table-row-level-0">
|
|
@foreach (var item in ColumnContext.HeaderColumns)
|
|
{
|
|
<td class="ant-table-cell" colspan="@item.ColSpan">
|
|
<Skeleton Active="true" ParagraphRows="1" Paragraph="false" ParagraphWidth="@item.Width"></Skeleton>
|
|
</td>
|
|
}
|
|
</tr>
|
|
</Placeholder>
|
|
</Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize>;
|
|
}
|
|
else
|
|
#endif
|
|
if (_total<=0 || showItems == null)
|
|
{
|
|
return @<tr class="ant-table-placeholder">
|
|
<td colspan="@(ColumnContext.Columns.Count + (ExpandTemplate != null? 1 : 0))" class="ant-table-cell">
|
|
@if (ScrollX != null)
|
|
{
|
|
<ResizeObserver RefBack="RefBack" OnResize="OnResize" />
|
|
|
|
@if (_tableWidth>0)
|
|
{
|
|
<div class="ant-table-expanded-row-fixed" style="width: @(_tableWidth)px; position: sticky; left: 0px; overflow: hidden;">
|
|
@if (EmptyTemplate!=null) { @EmptyTemplate } else { <Empty Simple /> }
|
|
</div>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
@if (EmptyTemplate!=null) { @EmptyTemplate } else { <Empty Simple /> }
|
|
}
|
|
</td>
|
|
</tr>
|
|
;
|
|
}
|
|
else if (_groupedColumns.Count>0 && level==0)
|
|
{
|
|
return _groups.Select((data, index) => GetGroupRowData(data, index, level, parentRowData?.Children))
|
|
.ForeachLoop(bodyRow());
|
|
}
|
|
#if NET5_0_OR_GREATER
|
|
else if (EnableVirtualization)
|
|
{
|
|
return @<Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize TItem="RowData<TItem>"
|
|
OverscanCount="10"
|
|
Items="showItems.Select((data, index) => GetRowData(data, index, level, parentRowData?.Children )).ToList()"
|
|
ItemContent="bodyRow()">
|
|
</Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize>;
|
|
}
|
|
#endif
|
|
else
|
|
{
|
|
{ @*Build will fail without this block*@ }
|
|
return showItems.Select((data, index) => GetRowData(data, index, level, parentRowData?.Children))
|
|
.ForeachLoop(bodyRow());
|
|
}
|
|
}
|
|
|
|
RenderFragment<RowData<TItem>> bodyRow()
|
|
{
|
|
return currentRowData =>
|
|
{
|
|
return @<TableRowWrapper RowData="currentRowData" @key="currentRowData.RowIndex">
|
|
@{
|
|
var currentDataItem = currentRowData.DataItem;
|
|
var rowAttributes = OnRow?.Invoke(currentRowData);
|
|
if (OnRowClick.HasDelegate)
|
|
{
|
|
rowAttributes ??= new Dictionary<string, object>();
|
|
rowAttributes.TryAdd("onclick", ((Action)delegate { OnRowClick.InvokeAsync(currentRowData); }));
|
|
}
|
|
|
|
var rowClassName = RowClassName(currentRowData);
|
|
<CascadingValue Value="true" Name="IsBody" IsFixed>
|
|
<CascadingValue Value="rowAttributes" Name="AntDesign.TableRow.RowAttributes">
|
|
<CascadingValue Value="rowClassName" Name="AntDesign.TableRow.RowClassName">
|
|
@if (RowTemplate != null)
|
|
{
|
|
@RowTemplate(currentRowData)
|
|
}
|
|
else
|
|
{
|
|
<TableRow>
|
|
@ChildContent(currentDataItem.Data)
|
|
</TableRow>
|
|
}
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
</CascadingValue>
|
|
|
|
// When expand button was clicked, would trigger here to add one more child level
|
|
@if (currentDataItem.HasChildren && currentRowData.Expanded)
|
|
{
|
|
currentRowData.Children??=new();
|
|
@body(SortFilterChildren(currentDataItem.Children), currentRowData);
|
|
}
|
|
@if (!currentDataItem.HasChildren && ExpandTemplate != null && RowExpandable(currentRowData) && currentRowData.Expanded)
|
|
{
|
|
<tr class="ant-table-expanded-row ant-table-expanded-row-level-1 @ExpandedRowClassName(currentRowData)"
|
|
style="@(currentRowData.Expanded?"":"display: none;")">
|
|
<td colspan="@(ColumnContext.Columns.Count+1)" class="ant-table-cell">
|
|
@ExpandTemplate(currentRowData)
|
|
</td>
|
|
</tr>
|
|
}
|
|
}
|
|
</TableRowWrapper>;
|
|
};
|
|
}
|
|
|
|
|
|
RenderFragment tfoot()
|
|
{
|
|
@if (_summaryRows?.Any() == true)
|
|
{
|
|
return@<CascadingValue Value="true" Name="IsSummary" IsFixed>
|
|
<tfoot class="ant-table-summary">
|
|
@foreach (var row in _summaryRows)
|
|
{
|
|
<tr>
|
|
@row.ChildContent
|
|
</tr>
|
|
}
|
|
</tfoot>
|
|
</CascadingValue>;
|
|
}
|
|
|
|
return builder => { };
|
|
}
|
|
} |