ant-design-blazor/components/table/Table.razor
Andrzej Bakun 152a574577 feat(module: overlay): OverlayTrigger not bound to a div (#937)
* feat(module:overlay): OverlayTrigger not bound to a div

* feat(module:overlay): OverlayTrigger not bound to a div

* feat(module:overlay): Logic transfer to single Overlay

* feat(module:overlay): remove obsolete duplication

* feat(module:Tooltip): Add for unbounded oncontextmenu event handler

* feat(module:tooltip): unbound js event listeners remove

* docs(module:tooltip): unbound explanation

* fix(module:button): attach Ref to top level html element @ref

* feat(module:dropdown&tooltip&popconfirm&popover): Overlay not bound to a div

* docs(module:dropdown&tooltip&popconfirm&popover): unbound explanation

* feat(module:OverlayTrigger): common logic relocation

* feat(module:overlaytrigger): Overlay not bound to a div

* feat(module:DatePicker): Overlay not bound to a div

* feat(module:select): Overlay not boud to div

* fix(module:select): onclickarrow event relocation

* fix(module:select): rename Show to OnArrowClick

* feat(module:avatar): Overlay not bound to a div

* docs(module:avatar): demo switch to unbound version

* feat(module:autocomplete): partial OverlayTrigger not bound to a div

* feat(module:slider): tooltip

* docs(module:slider): tooltip

* fix(module:overlay): add SetVisible method

* feat: set Ref where missing, performance

components register Ref when missing
IsFixed flag for CascadeValue changed
hard-code sequence numbers when using RenderTreeBuilder
Rate component use Tooltip Unbound version
Tabs test fix

* fix: revert changes (accidental)

* feat(module:upload): tooltip with unbound usage

* feat(module:table): column use of unbound tooltip

* feat(module:autocomplete):overlay unbound from div

* fix(module:upload): missing div restore

Co-authored-by: James Yeung <shunjiey@hotmail.com>
2021-01-21 17:20:10 +08:00

197 lines
9.4 KiB
C#

@namespace AntDesign
@inherits AntDomComponentBase
@using AntDesign.TableModels
@typeparam TItem
<div class="ant-table-wrapper" @ref="Ref">
<Spin Spinning="Loading">
@if (!HidePagination && PaginationPosition.Contains("top"))
{
<Pagination Class="@_paginationClass"
Total="Total"
PageSize="PageSize"
PageIndex="PageIndex"
OnPageIndexChange="HandlePageIndexChange"
OnPageSizeChange="HandlePageSizeChange" />
}
<CascadingValue Value="@this" TValue="ITable" IsFixed>
<CascadingValue Value=@typeof(TItem) Name="ItemType" IsFixed>
<CascadingValue Value="@ColumnContext" IsFixed>
<CascadingValue Name="IsInitialize" Value="true" IsFixed>
@ChildContent(_fieldModel)
</CascadingValue>
<div class="@ClassMapper.Class">
@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="table-layout: fixed;">
@colGroup((this, true))
@header(this)
</table>
</div>
<div class="ant-table-body" @ref="_tableBodyRef" style="@(ScrollX!=null?" overflow: auto scroll;":"overflow-y: scroll;") max-height: @((CssSizeLength)ScrollY)">
<table style="@(ScrollX!=null?$" width: {(CssSizeLength)ScrollX}; min-width: 100%;":"") table-layout: fixed;">
@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>
@ChildContent(_fieldModel)
</CascadingValue>
</tr>
@body((this, _showItems, 0))
</tbody>
</table>
</div>
}
else if (ScrollX != null)
{
<div class="ant-table-content" @ref="_tableBodyRef" style="overflow: auto hidden;">
<table style="width: @((CssSizeLength)ScrollX); min-width: 100%; table-layout: fixed;">
@colGroup((this, true))
@header(this)
<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>
@ChildContent(_fieldModel)
</CascadingValue>
</tr>
@body((this, _showItems, 0))
</tbody>
</table>
</div>
}
else
{
<div class="ant-table-content">
<table style="table-layout: @(_tableLayoutIsFixed?"fixed":"auto");">
@colGroup((this, true))
@header(this)
<tbody class="ant-table-tbody">
@body((this, _showItems, 0))
</tbody>
</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"))
{
<Pagination Class="@_paginationClass"
Total="Total"
PageSize="PageSize"
PageIndex="PageIndex"
OnPageIndexChange="HandlePageIndexChange"
OnPageSizeChange="HandlePageSizeChange" />
}
</Spin>
</div>
@code
{
RenderFragment<Table<TItem>> header = table =>
@<Template>
<thead class="ant-table-thead">
<tr>
<CascadingValue Name="IsHeader" Value="true" IsFixed>
@table.ChildContent(_fieldModel)
</CascadingValue>
@if (table.ScrollY != null)
{
<th class="ant-table-cell @(table._hasFixRight?"ant-table-cell-fix-right":"") ant-table-cell-scrollbar" style="@(table._hasFixRight?"position: sticky; right: 0px;":"")"></th>
}
</tr>
</thead>
</Template>;
RenderFragment<(Table<TItem> table, bool header)> colGroup = ctx =>
@<Template>
@{
var table = ctx.table;
var header = ctx.header;
}
<colgroup>
<CascadingValue Name="IsColGroup" Value="true" IsFixed>
@table.ChildContent(_fieldModel)
</CascadingValue>
@if (table.ScrollY != null && header)
{
<col style="width: @((CssSizeLength)table.ScrollBarWidth); min-width: @((CssSizeLength)table.ScrollBarWidth);" />
}
</colgroup>
</Template>;
RenderFragment<(Table<TItem> table, IEnumerable<TItem> showItems, int level)> body = context =>
@<Template>
@{
var table = context.table;
var showItems = context.showItems;
var level = context.level;
}
@if (table.Total <= 0)
{
<tr class="ant-table-placeholder">
<td colspan="@(table.ColumnContext.Columns.Count + (table.ExpandTemplate != null? 1 : 0))" class="ant-table-cell">
<Empty Simple />
</td>
</tr>
}
else if (showItems != null && table.ColumnContext.Columns.Count > 0)
{
for (int i = 0; i < showItems.Count(); i++)
{
var rowIndex = table.PageSize * (table.PageIndex - 1) + i + 1;
var data = showItems.ElementAt(i);
var cacheKey = data.GetHashCode();
if (!table._dataSourceCache.ContainsKey(cacheKey))
{
table._dataSourceCache[cacheKey] = new RowData<TItem>(rowIndex, table.PageIndex, data);
}
var currentRowData = table._dataSourceCache[cacheKey] ?? new RowData<TItem>(rowIndex, table.PageIndex, data);
var hasChildren = table.TreeChildren(data)?.Any() == true;
currentRowData.CacheKey = cacheKey;
currentRowData.Level = level;
currentRowData.HasChildren = hasChildren;
<tr @attributes="@(new Dictionary<string,object> { {"onclick", _callbackFactory.Create(table, () => table.RowClick(currentRowData)) } })"
data-row-key="@(rowIndex-1)" class="ant-table-row ant-table-row-level-@level @(currentRowData.Selected ? "ant-table-row-selected" : "")">
<CascadingValue Value="currentRowData" Name="RowData" IsFixed>
<CascadingValue Value="true" Name="IsBody" IsFixed>
@table.ChildContent(data)
</CascadingValue>
</CascadingValue>
</tr>
@if (hasChildren && currentRowData.Expanded)
{
@table.body((table, table.TreeChildren(data), level + 1));
}
@if (!hasChildren && table.ExpandTemplate != null && table.RowExpandable(currentRowData))
{
<tr class="ant-table-expanded-row ant-table-expanded-row-level-1" style="@(currentRowData.Expanded?"":"display: none;")">
<td colspan="@(table.ColumnContext.Columns.Count+1)" class="ant-table-cell">
@table.ExpandTemplate(currentRowData)
</td>
</tr>
}
}
}
</Template>;
}