LANCommander/LANCommander.UI/Components/DataList/DataList.razor
2025-11-13 21:04:39 -06:00

69 lines
No EOL
2.2 KiB
Text

@namespace LANCommander.UI.Components
@typeparam TItem
<div class="data-list">
<CascadingValue Value="_radio" Name="Radio">
<CascadingValue Value="_checkbox" Name="Checkbox">
<Flex Direction="FlexDirection.Vertical" Gap="Gap">
@foreach (var item in DataSource)
{
<CascadingValue Value="@(Value?.Equals(item) ?? Values?.Contains(item) ?? false)" Name="Selected">
<DataListItem
TItem="TItem"
Item="item"
OnSelectedChanged="(selected) => SelectionChanged(item, selected)"
ItemTemplate="ChildContent"/>
</CascadingValue>
}
</Flex>
</CascadingValue>
</CascadingValue>
</div>
@code {
[Parameter] public IEnumerable<TItem> DataSource { get; set; }
[Parameter] public TItem Value { get; set; } = default!;
[Parameter] public EventCallback<TItem> ValueChanged { get; set; }
[Parameter] public IEnumerable<TItem> Values { get; set; } = null!;
[Parameter] public EventCallback<IEnumerable<TItem>> ValuesChanged { get; set; }
[Parameter] public RenderFragment<TItem> ChildContent { get; set; }
[Parameter] public RenderFragment<TItem> ItemTemplate { get; set; }
[Parameter] public FlexGap Gap { get; set; } = FlexGap.Middle;
bool _radio;
bool _checkbox;
List<TItem> _selectedValues = new();
protected override void OnInitialized()
{
if (ValueChanged.HasDelegate)
_radio = true;
else if (ValuesChanged.HasDelegate)
_checkbox = true;
if (ChildContent == null && ItemTemplate != null)
ChildContent = ItemTemplate;
}
async Task SelectionChanged(TItem item, bool selected)
{
if (_radio && selected)
{
Value = item;
await ValueChanged.InvokeAsync(Value);
}
else if (_checkbox)
{
_selectedValues.Remove(item);
if (selected)
_selectedValues.Add(item);
Values = _selectedValues;
await ValuesChanged.InvokeAsync(Values);
}
}
}