Skip to content

Commit d748a59

Browse files
Css classes
edited readme
1 parent 968bb2b commit d748a59

3 files changed

Lines changed: 117 additions & 39 deletions

File tree

‎Components/FancyTable.razor‎

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
PagedItemsResult pagedItems = GetPagedItems();
66
}
77

8-
<div class="fancy-table-topbar d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
8+
<div class="@GetTopBarClass()">
99
@if (ShouldRenderPageSizeSelector)
1010
{
11-
<div class="fancy-page-size">
11+
<div class="@GetPageSizeContainerClass()">
1212
@if (PageSizeTemplate is not null)
1313
{
1414
@PageSizeTemplate(pagedItems.Context)
@@ -30,11 +30,13 @@
3030

3131
@if (ToolbarTemplate is not null)
3232
{
33-
@ToolbarTemplate
33+
<div class="@GetToolbarContainerClass()">
34+
@ToolbarTemplate
35+
</div>
3436
}
3537
else
3638
{
37-
<div class="d-flex ms-auto">
39+
<div class="@GetToolbarContainerClass()">
3840
<input class="form-control form-control-md" placeholder="@SearchPlaceholder" value="@SearchText" @oninput="OnSearchInput" @onkeyup="HandleSearchKeyPress" />
3941

4042
@if (string.IsNullOrWhiteSpace(SearchText))
@@ -116,14 +118,14 @@
116118

117119
@if (ShouldRenderPaginationFooter(pagedItems.Context))
118120
{
119-
<div class="fancy-pagination d-flex flex-wrap align-items-center justify-content-between gap-2 mt-3">
121+
<div class="@GetPaginationContainerClass()">
120122
@if (PaginationTemplate is not null)
121123
{
122124
@PaginationTemplate(pagedItems.Context)
123125
}
124126
else
125127
{
126-
<div class="fancy-pagination-summary text-muted small">
128+
<div class="@GetPaginationSummaryClass()">
127129
@if (PaginationSummaryTemplate is not null)
128130
{
129131
@PaginationSummaryTemplate(pagedItems.Context)
@@ -229,6 +231,21 @@
229231
[Parameter]
230232
public RenderFragment<FancyPaginationContext<TItem>>? PageSizeTemplate { get; set; }
231233

234+
[Parameter]
235+
public string? TopBarClass { get; set; }
236+
237+
[Parameter]
238+
public string? ToolbarContainerClass { get; set; }
239+
240+
[Parameter]
241+
public string? PageSizeContainerClass { get; set; }
242+
243+
[Parameter]
244+
public string? PaginationContainerClass { get; set; }
245+
246+
[Parameter]
247+
public string? PaginationSummaryClass { get; set; }
248+
232249
private readonly HashSet<string> HiddenColumns = new(StringComparer.Ordinal);
233250
private string? SortColumnKey;
234251
private bool SortAscending = true;
@@ -486,6 +503,19 @@
486503
return Enumerable.Range(startPage, endPage - startPage + 1).ToList();
487504
}
488505

506+
private string GetTopBarClass() => CombineClasses("fancy-table-topbar d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2", TopBarClass);
507+
508+
private string GetToolbarContainerClass() => CombineClasses("d-flex ms-auto", ToolbarContainerClass);
509+
510+
private string GetPageSizeContainerClass() => CombineClasses("fancy-page-size", PageSizeContainerClass);
511+
512+
private string GetPaginationContainerClass() => CombineClasses("fancy-pagination d-flex flex-wrap align-items-center justify-content-between gap-2 mt-3", PaginationContainerClass);
513+
514+
private string GetPaginationSummaryClass() => CombineClasses("fancy-pagination-summary text-muted small", PaginationSummaryClass);
515+
516+
private static string CombineClasses(string baseClass, string? additionalClass) =>
517+
string.IsNullOrWhiteSpace(additionalClass) ? baseClass : $"{baseClass} {additionalClass}";
518+
489519
private sealed class PagedItemsResult
490520
{
491521
public required IReadOnlyList<TItem> Items { get; init; }

‎Components/FancyTreeTable.razor‎

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,38 @@
55
PagedNodesResult pagedNodes = GetPagedNodes();
66
}
77

8-
<div class="fancy-table-topbar d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
9-
<div class="d-flex flex-wrap align-items-center gap-2">
10-
@if (TreeActionsTemplate is not null)
11-
{
12-
@TreeActionsTemplate(TreeContext)
13-
}
14-
15-
@if (ShouldRenderPageSizeSelector)
16-
{
17-
<div class="fancy-page-size">
18-
@if (PageSizeTemplate is not null)
19-
{
20-
@PageSizeTemplate(pagedNodes.Context)
21-
}
22-
else
23-
{
24-
<label class="d-inline-flex align-items-center gap-2 small text-muted">
25-
<span>Rows per page</span>
26-
<select class="form-select form-select-sm w-auto" value="@PaginationPageSize" @onchange="OnPageSizeChanged">
27-
@foreach (int option in EffectivePageSizeOptions)
28-
{
29-
<option value="@option">@(option == 0 ? "All" : option.ToString())</option>
30-
}
31-
</select>
32-
</label>
33-
}
34-
</div>
35-
}
36-
</div>
8+
<div class="@GetTopBarClass()">
9+
@if (ShouldRenderPageSizeSelector)
10+
{
11+
<div class="@GetPageSizeContainerClass()">
12+
@if (PageSizeTemplate is not null)
13+
{
14+
@PageSizeTemplate(pagedNodes.Context)
15+
}
16+
else
17+
{
18+
<label class="d-inline-flex align-items-center gap-2 small text-muted">
19+
<span>Rows per page</span>
20+
<select class="form-select form-select-sm w-auto" value="@PaginationPageSize" @onchange="OnPageSizeChanged">
21+
@foreach (int option in EffectivePageSizeOptions)
22+
{
23+
<option value="@option">@(option == 0 ? "All" : option.ToString())</option>
24+
}
25+
</select>
26+
</label>
27+
}
28+
</div>
29+
}
3730

3831
@if (ToolbarTemplate is not null)
3932
{
40-
@ToolbarTemplate
33+
<div class="@GetToolbarContainerClass()">
34+
@ToolbarTemplate
35+
</div>
4136
}
4237
else
4338
{
44-
<div class="d-flex ms-auto">
39+
<div class="@GetToolbarContainerClass()">
4540
<input class="form-control form-control-md" placeholder="@SearchPlaceholder" value="@SearchText" @oninput="OnSearchInput" @onkeyup="HandleSearchKeyPress" />
4641

4742
@if (string.IsNullOrWhiteSpace(SearchText))
@@ -60,6 +55,13 @@
6055
}
6156
</div>
6257

58+
@if (TreeActionsTemplate is not null)
59+
{
60+
<div class="@GetTreeActionsContainerClass()">
61+
@TreeActionsTemplate(TreeContext)
62+
</div>
63+
}
64+
6365
<div class="tree-table-container">
6466
<table class="tree-table">
6567
<thead>
@@ -126,14 +128,14 @@
126128

127129
@if (ShouldRenderPaginationFooter(pagedNodes.Context))
128130
{
129-
<div class="fancy-pagination d-flex flex-wrap align-items-center justify-content-between gap-2 mt-3">
131+
<div class="@GetPaginationContainerClass()">
130132
@if (PaginationTemplate is not null)
131133
{
132134
@PaginationTemplate(pagedNodes.Context)
133135
}
134136
else
135137
{
136-
<div class="fancy-pagination-summary text-muted small">
138+
<div class="@GetPaginationSummaryClass()">
137139
@if (PaginationSummaryTemplate is not null)
138140
{
139141
@PaginationSummaryTemplate(pagedNodes.Context)
@@ -254,6 +256,24 @@
254256
[Parameter]
255257
public RenderFragment<FancyTreeTableContext<TItem>>? TreeActionsTemplate { get; set; }
256258

259+
[Parameter]
260+
public string? TopBarClass { get; set; }
261+
262+
[Parameter]
263+
public string? ToolbarContainerClass { get; set; }
264+
265+
[Parameter]
266+
public string? PageSizeContainerClass { get; set; }
267+
268+
[Parameter]
269+
public string? TreeActionsContainerClass { get; set; }
270+
271+
[Parameter]
272+
public string? PaginationContainerClass { get; set; }
273+
274+
[Parameter]
275+
public string? PaginationSummaryClass { get; set; }
276+
257277
private readonly HashSet<string> HiddenColumns = new(StringComparer.Ordinal);
258278
private readonly Dictionary<TItem, bool> ExpandedStates = new();
259279
private readonly List<TreeNodeState<TItem>> RootNodes = [];
@@ -744,6 +764,21 @@
744764
return Enumerable.Range(startPage, endPage - startPage + 1).ToList();
745765
}
746766

767+
private string GetTopBarClass() => CombineClasses("fancy-table-topbar d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2", TopBarClass);
768+
769+
private string GetToolbarContainerClass() => CombineClasses("d-flex ms-auto", ToolbarContainerClass);
770+
771+
private string GetPageSizeContainerClass() => CombineClasses("fancy-page-size", PageSizeContainerClass);
772+
773+
private string GetTreeActionsContainerClass() => CombineClasses("fancy-tree-actions", TreeActionsContainerClass);
774+
775+
private string GetPaginationContainerClass() => CombineClasses("fancy-pagination d-flex flex-wrap align-items-center justify-content-between gap-2 mt-3", PaginationContainerClass);
776+
777+
private string GetPaginationSummaryClass() => CombineClasses("fancy-pagination-summary text-muted small", PaginationSummaryClass);
778+
779+
private static string CombineClasses(string baseClass, string? additionalClass) =>
780+
string.IsNullOrWhiteSpace(additionalClass) ? baseClass : $"{baseClass} {additionalClass}";
781+
747782
private sealed class PagedNodesResult
748783
{
749784
public required IReadOnlyList<TreeNodeState<TItem>> Items { get; init; }

‎README.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ https://www.nuget.org/packages/SoPro.FancyTable
5353
- Optional leading-content hook for the first cell via `RowLeadingContentTemplate`
5454
- Row classes via `RowClassSelector`
5555
- Header and cell styling via `HeaderClass` and `CellClass`
56+
- Wrapper layout classes for toolbar, tree actions, page size, and pagination containers
5657

5758
## Parameters
5859

@@ -79,6 +80,11 @@ https://www.nuget.org/packages/SoPro.FancyTable
7980
| `PaginationSummaryTemplate` | `RenderFragment<FancyPaginationContext<TItem>>?` | Custom summary content for the default footer |
8081
| `PaginationTemplate` | `RenderFragment<FancyPaginationContext<TItem>>?` | Replaces the visible footer pager area |
8182
| `PageSizeTemplate` | `RenderFragment<FancyPaginationContext<TItem>>?` | Replaces the page-size selector area above the table |
83+
| `TopBarClass` | `string?` | Additional CSS classes for the top bar wrapper |
84+
| `ToolbarContainerClass` | `string?` | Additional CSS classes for the toolbar/search container |
85+
| `PageSizeContainerClass` | `string?` | Additional CSS classes for the page-size wrapper |
86+
| `PaginationContainerClass` | `string?` | Additional CSS classes for the pagination footer wrapper |
87+
| `PaginationSummaryClass` | `string?` | Additional CSS classes for the pagination summary wrapper |
8288

8389
## Tree Table Parameters
8490

@@ -91,6 +97,7 @@ https://www.nuget.org/packages/SoPro.FancyTable
9197
| `ExpandLabel` | `string` | Accessible label for collapsed nodes (default: `"Expand"`) |
9298
| `CollapseLabel` | `string` | Accessible label for expanded nodes (default: `"Collapse"`) |
9399
| `TreeActionsTemplate` | `RenderFragment<FancyTreeTableContext<TItem>>?` | Renders custom tree-level actions such as expand/collapse all |
100+
| `TreeActionsContainerClass` | `string?` | Additional CSS classes for the tree actions wrapper |
94101

95102
## Row Context
96103

@@ -352,6 +359,8 @@ This example covers:
352359

353360
When pagination is enabled, `FancyTable` paginates after search and sorting. `CurrentPage` and `PageSize` can be bound to keep state stable across parent rerenders.
354361

362+
Wrapper class parameters append to the built-in layout classes, so utility classes such as `d-inline-flex`, `justify-content-end`, or `gap-3` can adjust the layout without replacing templates.
363+
355364
## Tree Table Example
356365

357366
`FancyTreeTable<TItem>` works with nested data while keeping the same column definition style:
@@ -368,6 +377,10 @@ When pagination is enabled, `FancyTable` paginates after search and sorting. `Cu
368377
PaginationEnabled="true"
369378
PageSize="5"
370379
ShowPageSizeSelector="true"
380+
TopBarClass="justify-content-end"
381+
PageSizeContainerClass="me-auto"
382+
TreeActionsContainerClass="d-inline-flex align-items-center gap-2"
383+
PaginationContainerClass="justify-content-end"
371384
TreeActionsTemplate="RuleTreeActions"
372385
RowTemplate="SectionHeaderTemplate"
373386
RowTemplateSelector="context => context.Item.IsSectionHeader"

0 commit comments

Comments
 (0)