Skip to content

Commit 4a68d78

Browse files
github-actions[bot]dimodiyordan-mitev
authored
Merge auto-layout-2828 into production (#2837)
* docs(Grid): Revamp Column Width article * Update components/grid/columns/width.md * Update components/grid/columns/width.md Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com> * Update components/grid/columns/width.md Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com> * Update components/grid/columns/width.md Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com> * Update components/grid/columns/width.md Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com> * Update components/grid/columns/width.md Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com> * Update components/grid/columns/width.md Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com> * Improve table design and port to TreeList * Update components/treelist/columns/width.md --------- Co-authored-by: Dimo Dimov <961014+dimodi@users.noreply.github.com> Co-authored-by: Yordan <60105689+yordan-mitev@users.noreply.github.com>
1 parent 7519abb commit 4a68d78

File tree

3 files changed

+329
-19
lines changed

3 files changed

+329
-19
lines changed

_contentTemplates/common/parameters-table-styles.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,36 @@
66
}
77
</style>
88
#end
9+
10+
#multidimensional-table
11+
<style>
12+
table.multi-dimensional-table {
13+
border-collapse: collapse;
14+
border-radius: 0 0 0 0;
15+
}
16+
17+
.multi-dimensional-table th {
18+
padding: 8px;
19+
background: var(--bg-table-th-color);
20+
color: var(--table-th-color);
21+
font-weight: 700;
22+
text-align: left;
23+
font-size: 18px;
24+
text-align: center;
25+
}
26+
.multi-dimensional-table,
27+
.multi-dimensional-table th,
28+
.multi-dimensional-table td {
29+
border: 1px solid rgba(127, 127, 127, .2);
30+
}
31+
32+
table.multi-dimensional-table ul {
33+
margin: .5em 0;
34+
}
35+
36+
table.multi-dimensional-table li {
37+
font-size: inherit;
38+
font-weight: inherit;
39+
}
40+
</style>
41+
#end

components/grid/columns/width.md

Lines changed: 130 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,145 @@ published: True
88
position: 4
99
---
1010

11-
# Grid Column Width Behavior
11+
# Grid Column Width
1212

13-
This article explains how the grid column width behaves depending on the settings applied by the developer.
13+
This article explains how to set Grid column widths and how the component behaves, depending on its column width configuration.
1414

15-
You can set the grid column `Width` parameter in any CSS unit, such as `px`, `%`, `vw`, `em`, `rem`. You can read more on how to set sizes in Telerik components in the [Dimensions](slug:common-features/dimensions) article. You must, however, provide the unit so that the browser can understand it.
15+
## Basics
1616

17-
With regard to the widths of its columns, the scrollable (default) Grid typically behaves as any regular HTML table with a `table-layout: fixed` and `width: 100%`.
17+
The Grid renders separate HTML `<table>` elements for its header, data, and footer areas. This allows users to scroll the data area vertically, while the header and footer areas remain visible at all times. The Grid tables apply `table-layout: fixed` and `width: 100%` CSS styles to ensure column alignment between the three areas.
1818

19-
* When all column widths are explicitly set and the cumulative column width is greater than the available Grid width, a horizontal scrollbar appears and all set column widths are respected.
19+
You can set the Grid column `Width` parameter in any CSS unit, such as `px`, `%`, `vw`, `em`, `rem`. Unit-less `Width` values are not supported. You can read more on how to set sizes in Telerik components in the [Dimensions](slug:common-features/dimensions) article.
2020

21-
* When all column widths are explicitly set and the cumulative column width is less than the available Grid width, the remaining width is distributed evenly between all columns.
21+
## Column Width Behavior
2222

23-
* When only some column widths are set and the cumulative width of the columns with set widths is greater than the available Grid width, a horizontal scrollbar appears and all set column widths are respected. Columns with no set width are invisible as their width is `0`.
23+
The Grid column width settings can vary and result in the following behaviors:
2424

25-
* When only some column widths are set and the cumulative width of columns with set widths is less than the available Grid width, the widths of the columns with a set width are respected and the remaining width is distributed evenly between the other columns.
25+
@[template](/_contentTemplates/common/parameters-table-styles.md#multidimensional-table)
2626

27-
* When no column widths are set, the available width is distributed evenly between all Grid columns.
27+
<table class="multi-dimensional-table">
28+
<colgroup><col style="width: 112px" /><col style="width: 70px" /><col /><col /></colgroup>
29+
<tr>
30+
<th>&nbsp;</th>
31+
<th>&nbsp;</th>
32+
<th colspan="2">The Sum of All Set Column Widths Is:</th>
33+
</tr>
34+
<tr>
35+
<th>&nbsp;</th>
36+
<th>&nbsp;</th>
37+
<th>Greater Than the Grid Width</th>
38+
<th>Less Than the Grid Width</th>
39+
</tr>
40+
<tr>
41+
<th style="writing-mode: vertical-lr;" rowspan="3">How Many Columns Have Width:</th>
42+
<th>All</th>
43+
<td><ul><li>All columns respect their <code>Width</code> setting.</li><li>A horizontal scrollbar appears.</li></ul></td>
44+
<td><ul><li>All columns expand beyond their <code>Width</code> setting to fill the available space in the Grid.</li><li>There is no horizontal scrollbar.</li></ul></td>
45+
</tr>
46+
<tr>
47+
<th>Some</th>
48+
<td><ul><li>All columns respect their <code>Width</code> setting, if exists.</li><li>All columns without a <code>Width</code> shrink and disappear.</li><li>A horizontal scrollbar appears.</li></ul></td>
49+
<td><ul><li>All columns respect their <code>Width</code> setting, if exists.</li><li>All columns without a <code>Width</code> shrink or expand, depending on the remaining space in the Grid.</li><li>There is no horizontal scrollbar.</li></ul></td>
50+
</tr>
51+
<tr>
52+
<th>None</th>
53+
<td colspan="2"><ul style="margin: .5em auto; width: max-content;"><li>All columns have the same width, which depends on the Grid width.</li><li>There is no horizontal scrollbar.</li></ul></td>
54+
</tr>
55+
</table>
2856

29-
* To allow the users to auto-fit the column widths to the content, enable [column resizing](slug:components/grid/columns/resize) - a double click on the border between the headers will have the grid adjust the column width according to the size of the data, headers and footers content. It is also possible to [auto-fit columns programmatically](slug:components/grid/columns/resize#autofit-columns).
57+
To allow the users to adjust or auto-fit the column widths to the content, enable [Grid column resizing](slug:components/grid/columns/resize). You can also [resize columns through the Grid state](slug:grid-state#setstateasync) or [auto-fit columns programmatically](slug:components/grid/columns/resize#autofit-columns).
58+
59+
> Single table rendering and automatic table layout are not supported.
60+
61+
## Recommendations
62+
63+
For predictable and user-friendly behavior, consider the following Grid configuration:
64+
65+
* If the Grid has a fixed width and you need horizontal scrolling, set widths to all columns. Use absolute units that do not depend on the browser viewport size.
66+
* If the Grid does not need horizontal scrolling and is not likely to shrink too much, then leave at least one column without a width. This ensures that all set column widths are respected and the width-less columns take up the remaining space.
67+
* If the Grid width is unpredictable and the width-less columns may shrink too much, then apply a `min-width` style to the Grid tables, according to the example below.
68+
69+
>caption Apply a minimum width to the Grid table in a responsive layout
70+
71+
````RAZOR
72+
<TelerikSplitter Orientation="@SplitterOrientation.Horizontal">
73+
<SplitterPanes>
74+
<SplitterPane Size="120px" Collapsible="true">
75+
<p>Resize this pane to resize the Grid.</p>
76+
</SplitterPane>
77+
<SplitterPane>
78+
<TelerikGrid Data="@GridData"
79+
Class="grid-min-width"
80+
FilterMode="@GridFilterMode.FilterMenu"
81+
Resizable="true"
82+
Sortable="true">
83+
<GridAggregates>
84+
<GridAggregate Field="@nameof(Product.Name)" Aggregate="@GridAggregateType.Count" />
85+
<GridAggregate Field="@nameof(Product.Price)" Aggregate="@GridAggregateType.Average" />
86+
<GridAggregate Field="@nameof(Product.Quantity)" Aggregate="@GridAggregateType.Sum" />
87+
</GridAggregates>
88+
<GridColumns>
89+
<GridColumn Field="@nameof(Product.Id)" Width="90px" />
90+
<GridColumn Field="@nameof(Product.Name)">
91+
<FooterTemplate>
92+
Count: @context.Count
93+
</FooterTemplate>
94+
</GridColumn>
95+
<GridColumn Field="@nameof(Product.Price)" Width="110px">
96+
<FooterTemplate>
97+
Average: @context.Average
98+
</FooterTemplate>
99+
</GridColumn>
100+
<GridColumn Field="@nameof(Product.Quantity)" Width="130px">
101+
<FooterTemplate>
102+
Sum: @context.Sum
103+
</FooterTemplate>
104+
</GridColumn>
105+
<GridColumn Field="@nameof(Product.ReleaseDate)" DisplayFormat="{0:D}" />
106+
<GridColumn Field="@nameof(Product.IsActive)" Width="120px" />
107+
</GridColumns>
108+
</TelerikGrid>
109+
</SplitterPane>
110+
</SplitterPanes>
111+
</TelerikSplitter>
112+
113+
<style>
114+
.grid-min-width .k-table {
115+
/* 450px set widths + at least 150px for each remaining column */
116+
min-width: 750px;
117+
}
118+
</style>
119+
120+
@code {
121+
private List<Product> GridData { get; set; } = new();
122+
123+
protected override void OnInitialized()
124+
{
125+
for (int i = 1; i <= 5; i++)
126+
{
127+
GridData.Add(new Product()
128+
{
129+
Id = i,
130+
Name = $"Name {i}",
131+
Price = Random.Shared.Next(1, 100) * 1.23m,
132+
Quantity = Random.Shared.Next(0, 1000),
133+
ReleaseDate = DateTime.Today.AddDays(-Random.Shared.Next(60, 1000)),
134+
IsActive = i % 4 > 0
135+
});
136+
}
137+
}
138+
139+
public class Product
140+
{
141+
public int Id { get; set; }
142+
public string Name { get; set; } = string.Empty;
143+
public decimal Price { get; set; }
144+
public int Quantity { get; set; }
145+
public DateTime ReleaseDate { get; set; }
146+
public bool IsActive { get; set; }
147+
}
148+
}
149+
````
30150

31151
# See Also
32152

components/treelist/columns/width.md

Lines changed: 166 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,181 @@ published: True
88
position: 4
99
---
1010

11-
# TreeList Column Width Behavior
11+
# TreeList Column Width
1212

13-
This article explains how the treelist column width behaves depending on the settings applied by the developer.
13+
This article explains how to set TreeList column widths and how the component behaves, depending on its column width configuration.
1414

15-
With regard to the widths of its columns, the scrollable (default) treelist typically behaves as any regular HTML table with a `table-layout: fixed`.
15+
## Basics
1616

17-
* When all column widths are explicitly set and the cumulative column width is greater than the available treelist width, a horizontal scrollbar appears and all set column widths are respected.
17+
The TreeList renders separate HTML `<table>` elements for its header and data areas. This allows users to scroll the data area vertically, while the header area remains visible at all times. The TreeList tables apply `table-layout: fixed` and `width: 100%` CSS styles to ensure column alignment between the three areas.
1818

19-
* When all column widths are explicitly set and the cumulative column width is less than the available treelist width, the remaining width is distributed evenly between all columns.
19+
You can set the TreeList column `Width` parameter in any CSS unit, such as `px`, `%`, `vw`, `em`, `rem`. Unit-less `Width` values are not supported. You can read more on how to set sizes in Telerik components in the [Dimensions](slug:common-features/dimensions) article.
2020

21-
* When only some column widths are set and the cumulative width of the columns with set widths is greater than the available treelist width, a horizontal scrollbar appears and all set column widths are respected. Columns with no set width are invisible as their width is `0`.
21+
## Column Width Behavior
2222

23-
* When only some column widths are set and the cumulative width of columns with set widths is less than the available treelist width, the widths of the columns with a set width are respected and the remaining width is distributed evenly between the other columns.
23+
The TreeList column width settings can vary and result in the following behaviors:
2424

25-
* When no column widths are set, the available width is distributed evenly between all treelist columns.
25+
@[template](/_contentTemplates/common/parameters-table-styles.md#multidimensional-table)
2626

27-
* To allow the users to auto-fit the column widths to the content, enable [column resizing](slug:treelist-columns-resize) - a double click on the border between the headers will have the treelist adjust the column width according to the size of the data, and header content. It is also possible to [auto-fit columns programmatically](slug:treelist-columns-resize#autofit-columns).
27+
<table class="multi-dimensional-table">
28+
<colgroup><col style="width: 112px" /><col style="width: 70px" /><col /><col /></colgroup>
29+
<tr>
30+
<th>&nbsp;</th>
31+
<th>&nbsp;</th>
32+
<th colspan="2">The Sum of All Set Column Widths Is:</th>
33+
</tr>
34+
<tr>
35+
<th>&nbsp;</th>
36+
<th>&nbsp;</th>
37+
<th>Greater Than the TreeList Width</th>
38+
<th>Less Than the TreeList Width</th>
39+
</tr>
40+
<tr>
41+
<th style="writing-mode: vertical-lr;" rowspan="3">How Many Columns Have Width:</th>
42+
<th>All</th>
43+
<td><ul><li>All columns respect their <code>Width</code> setting.</li><li>A horizontal scrollbar appears.</li></ul></td>
44+
<td><ul><li>All columns expand beyond their <code>Width</code> setting to fill the available space in the TreeList.</li><li>There is no horizontal scrollbar.</li></ul></td>
45+
</tr>
46+
<tr>
47+
<th>Some</th>
48+
<td><ul><li>All columns respect their <code>Width</code> setting, if exists.</li><li>All columns without a <code>Width</code> shrink and disappear.</li><li>A horizontal scrollbar appears.</li></ul></td>
49+
<td><ul><li>All columns respect their <code>Width</code> setting, if exists.</li><li>All columns without a <code>Width</code> shrink or expand, depending on the remaining space in the TreeList.</li><li>There is no horizontal scrollbar.</li></ul></td>
50+
</tr>
51+
<tr>
52+
<th>None</th>
53+
<td colspan="2"><ul style="margin: .5em auto; width: max-content;"><li>All columns have the same width, which depends on the TreeList width.</li><li>There is no horizontal scrollbar.</li></ul></td>
54+
</tr>
55+
</table>
2856

57+
To allow the users to adjust or auto-fit the column widths to the content, enable [TreeList column resizing](slug:treelist-columns-resize). You can also [resize columns through the TreeList state](slug:treelist-state#methods) or [auto-fit columns programmatically](slug:treelist-columns-resize#autofit-columns).
58+
59+
> Single table rendering and automatic table layout are not supported.
60+
61+
## Recommendations
62+
63+
For predictable and user-friendly behavior, consider the following TreeList configuration:
64+
65+
* If the TreeList has a fixed width and you need horizontal scrolling, set widths to all columns. Use absolute units that do not depend on the browser viewport size.
66+
* If the TreeList does not need horizontal scrolling and is not likely to shrink too much, then leave at least one column without a width. This ensures that all set column widths are respected and the width-less columns take up the remaining space.
67+
* If the TreeList width is unpredictable and the width-less columns may shrink too much, then apply a `min-width` style to the TreeList tables, according to the example below.
68+
69+
>caption Apply a minimum width to the TreeList table in a responsive layout
70+
71+
````RAZOR
72+
<TelerikSplitter Orientation="@SplitterOrientation.Horizontal">
73+
<SplitterPanes>
74+
<SplitterPane Size="120px" Collapsible="true">
75+
<p>Resize this pane to resize the TreeList.</p>
76+
</SplitterPane>
77+
<SplitterPane>
78+
<TelerikTreeList Data="@TreeListData"
79+
IdField="@nameof(Employee.Id)"
80+
ParentIdField="@nameof(Employee.ParentId)"
81+
FilterMode="TreeListFilterMode.FilterMenu"
82+
Sortable="true"
83+
Height="360px"
84+
Class="treelist-min-width">
85+
<TreeListColumns>
86+
<TreeListColumn Field="@nameof(Employee.Id)" Width="90px" />
87+
<TreeListColumn Field="@nameof(Employee.Name)" Expandable="true" />
88+
<TreeListColumn Field="@nameof(Employee.Salary)" DisplayFormat="{0:C2}" Width="120px" />
89+
<TreeListColumn Field="@nameof(Employee.HireDate)" DisplayFormat="{0:d}" Width="150px" />
90+
<TreeListColumn Field="@nameof(Employee.IsDriver)" Width="120px" />
91+
</TreeListColumns>
92+
</TelerikTreeList>
93+
</SplitterPane>
94+
</SplitterPanes>
95+
</TelerikSplitter>
96+
97+
<style>
98+
.treelist-min-width .k-table {
99+
/* 480px set widths + at least 270px for the emaining Name column */
100+
min-width: 750px;
101+
}
102+
</style>
103+
104+
@code {
105+
private List<Employee>? TreeListData { get; set; }
106+
107+
private EmployeeService TreeListEmployeeService { get; set; } = new();
108+
109+
protected override async Task OnInitializedAsync()
110+
{
111+
TreeListData = await TreeListEmployeeService.Read();
112+
}
113+
114+
public class Employee
115+
{
116+
public int Id { get; set; }
117+
public int? ParentId { get; set; }
118+
public bool HasChildren { get; set; }
119+
public string Name { get; set; } = string.Empty;
120+
public decimal? Salary { get; set; }
121+
public DateTime? HireDate { get; set; }
122+
public bool IsDriver { get; set; }
123+
}
124+
125+
#region Data Service
126+
127+
public class EmployeeService
128+
{
129+
private List<Employee> Items { get; set; } = new();
130+
131+
private readonly int TreeLevelCount;
132+
private readonly int RootItemCount;
133+
private readonly int ChildItemCount;
134+
135+
private int LastId { get; set; }
136+
private Random Rnd { get; set; } = Random.Shared;
137+
138+
public async Task<List<Employee>> Read()
139+
{
140+
await SimulateAsyncOperation();
141+
return Items;
142+
}
143+
144+
private async Task SimulateAsyncOperation()
145+
{
146+
await Task.Delay(100);
147+
}
148+
149+
private void PopulateChildren(List<Employee> items, int? parentId, int level)
150+
{
151+
int itemCount = level == 1 ? RootItemCount : ChildItemCount;
152+
for (int i = 1; i <= itemCount; i++)
153+
{
154+
int itemId = ++LastId;
155+
items.Add(new Employee()
156+
{
157+
Id = itemId,
158+
ParentId = parentId,
159+
HasChildren = level < TreeLevelCount,
160+
Name = $"Employee Name {itemId}", // {level}-{i}
161+
Salary = Rnd.Next(1_000, 10_000) * 1.23m,
162+
HireDate = DateTime.Today.AddDays(-Rnd.Next(365, 3650)),
163+
IsDriver = itemId % 2 == 0
164+
});
165+
if (level < TreeLevelCount)
166+
{
167+
PopulateChildren(items, itemId, level + 1);
168+
}
169+
}
170+
}
171+
172+
public EmployeeService(int treeLevelCount = 3, int rootItemCount = 3, int childItemCount = 2)
173+
{
174+
TreeLevelCount = treeLevelCount;
175+
RootItemCount = rootItemCount;
176+
ChildItemCount = childItemCount;
177+
List<Employee> items = new();
178+
PopulateChildren(items, null, 1);
179+
Items = items;
180+
}
181+
}
182+
183+
#endregion Data Service
184+
}
185+
````
29186

30187
# See Also
31188

0 commit comments

Comments
 (0)