From 28f76be108ba62fa4e99042790774f6296ad4136 Mon Sep 17 00:00:00 2001 From: Pat Hartl Date: Mon, 10 Nov 2025 18:07:13 -0600 Subject: [PATCH] New DataList component --- .../Components/DataList/DataList.razor | 65 +++++++++++++++++++ .../DataList/DataListInputPosition.cs | 7 +- .../Components/DataList/DataListItem.razor | 48 ++++++++++++++ .../DataList/DataListItemInput.razor | 31 +++++++++ 4 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 LANCommander.UI/Components/DataList/DataList.razor create mode 100644 LANCommander.UI/Components/DataList/DataListItem.razor create mode 100644 LANCommander.UI/Components/DataList/DataListItemInput.razor diff --git a/LANCommander.UI/Components/DataList/DataList.razor b/LANCommander.UI/Components/DataList/DataList.razor new file mode 100644 index 00000000..c84fb531 --- /dev/null +++ b/LANCommander.UI/Components/DataList/DataList.razor @@ -0,0 +1,65 @@ +@namespace LANCommander.UI.Components +@typeparam TItem + +
+ + + @foreach (var item in DataSource) + { + + + + } + + +
+ +@code { + [Parameter] public IEnumerable DataSource { get; set; } + [Parameter] public TItem Value { get; set; } + [Parameter] public EventCallback ValueChanged { get; set; } + [Parameter] public IEnumerable Values { get; set; } + [Parameter] public EventCallback> ValuesChanged { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } + [Parameter] public RenderFragment ItemTemplate { get; set; } + + bool _radio; + bool _checkbox; + + List _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); + } + } +} \ No newline at end of file diff --git a/LANCommander.UI/Components/DataList/DataListInputPosition.cs b/LANCommander.UI/Components/DataList/DataListInputPosition.cs index 1704e316..16839717 100644 --- a/LANCommander.UI/Components/DataList/DataListInputPosition.cs +++ b/LANCommander.UI/Components/DataList/DataListInputPosition.cs @@ -1,6 +1,7 @@ -namespace LANCommander.UI.Components.DataList; +namespace LANCommander.UI.Components; -public class DataListInputPosition +public enum DataListInputPosition { - + Left, + Right, } \ No newline at end of file diff --git a/LANCommander.UI/Components/DataList/DataListItem.razor b/LANCommander.UI/Components/DataList/DataListItem.razor new file mode 100644 index 00000000..f3cff779 --- /dev/null +++ b/LANCommander.UI/Components/DataList/DataListItem.razor @@ -0,0 +1,48 @@ +@namespace LANCommander.UI.Components +@typeparam TItem + + + + @if (InputPosition == DataListInputPosition.Left) + { + + } + + @ItemTemplate(Item) + + @if (InputPosition == DataListInputPosition.Right) + { + + } + + + +@code { + [CascadingParameter(Name = "Selected")] + public bool Selected { get; set; } + + [CascadingParameter(Name = "Radio")] + public bool Radio { get; set; } + + [CascadingParameter(Name = "Checkbox")] + public bool Checkbox { get; set; } + + [CascadingParameter(Name = "InputPosition")] + public DataListInputPosition InputPosition { get; set; } + + [CascadingParameter(Name = "SelectionTemplate")] + public RenderFragment SelectionTemplate { get; set; } + + [Parameter] public TItem Item { get; set; } + [Parameter] public RenderFragment ItemTemplate { get; set; } + [Parameter] public EventCallback OnSelectedChanged { get; set; } + [Parameter] public FlexAlign Align { get; set; } = FlexAlign.Normal; + [Parameter] public FlexJustify Justify { get; set; } = FlexJustify.Center; + [Parameter] public FlexGap Gap { get; set; } = FlexGap.Normal; + + private async Task ToggleSelection() + { + if (OnSelectedChanged.HasDelegate) + await OnSelectedChanged.InvokeAsync(!Selected); + } +} \ No newline at end of file diff --git a/LANCommander.UI/Components/DataList/DataListItemInput.razor b/LANCommander.UI/Components/DataList/DataListItemInput.razor new file mode 100644 index 00000000..0eeccd22 --- /dev/null +++ b/LANCommander.UI/Components/DataList/DataListItemInput.razor @@ -0,0 +1,31 @@ +@namespace LANCommander.UI.Components +@typeparam TItem + +@if (SelectionTemplate != null) +{ + @SelectionTemplate((Item, Selected)) +} +else if (Radio) +{ + +} +else if (Checkbox) +{ + +} + +@code { + [CascadingParameter(Name = "Item")] + public TItem Item { get; set; } + + [CascadingParameter(Name = "Selected")] + public bool Selected { get; set; } + + [CascadingParameter(Name = "Radio")] + public bool Radio { get; set; } + + [CascadingParameter(Name = "Checkbox")] + public bool Checkbox { get; set; } + + [Parameter] public RenderFragment<(TItem, bool)> SelectionTemplate { get; set; } +} \ No newline at end of file