Skip to content

Commit 78567b0

Browse files
feat(popups): popup causes scroll - repro and solution (#91)
* feat(popups): popup causes scroll - repro and solution * chore: update to 2.24.0
1 parent 26f15d1 commit 78567b0

37 files changed

+1545
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.31313.79
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "popup_causes_scroll.Server", "popup-causes-scroll\Server\popup_causes_scroll.Server.csproj", "{7A372C00-4816-4D03-B57F-B05298167B58}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "popup_causes_scroll.Client", "popup-causes-scroll\Client\popup_causes_scroll.Client.csproj", "{477F1BBD-948F-4AA6-BA68-88D1430591E5}"
9+
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "popup_causes_scroll.Shared", "popup-causes-scroll\Shared\popup_causes_scroll.Shared.csproj", "{06FDEAE2-B2B0-48FE-8B9E-872F185FF1FE}"
11+
EndProject
12+
Global
13+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
14+
Debug|Any CPU = Debug|Any CPU
15+
Release|Any CPU = Release|Any CPU
16+
EndGlobalSection
17+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
18+
{7A372C00-4816-4D03-B57F-B05298167B58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19+
{7A372C00-4816-4D03-B57F-B05298167B58}.Debug|Any CPU.Build.0 = Debug|Any CPU
20+
{7A372C00-4816-4D03-B57F-B05298167B58}.Release|Any CPU.ActiveCfg = Release|Any CPU
21+
{7A372C00-4816-4D03-B57F-B05298167B58}.Release|Any CPU.Build.0 = Release|Any CPU
22+
{477F1BBD-948F-4AA6-BA68-88D1430591E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{477F1BBD-948F-4AA6-BA68-88D1430591E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{477F1BBD-948F-4AA6-BA68-88D1430591E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
25+
{477F1BBD-948F-4AA6-BA68-88D1430591E5}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{06FDEAE2-B2B0-48FE-8B9E-872F185FF1FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{06FDEAE2-B2B0-48FE-8B9E-872F185FF1FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{06FDEAE2-B2B0-48FE-8B9E-872F185FF1FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{06FDEAE2-B2B0-48FE-8B9E-872F185FF1FE}.Release|Any CPU.Build.0 = Release|Any CPU
30+
EndGlobalSection
31+
GlobalSection(SolutionProperties) = preSolution
32+
HideSolutionNode = FALSE
33+
EndGlobalSection
34+
GlobalSection(ExtensibilityGlobals) = postSolution
35+
SolutionGuid = {9341BCD3-8C51-4DEA-9F60-213D45407BFF}
36+
EndGlobalSection
37+
EndGlobal
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Router AppAssembly="@typeof(Program).Assembly">
2+
<Found Context="routeData">
3+
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
4+
</Found>
5+
<NotFound>
6+
<LayoutView Layout="@typeof(MainLayout)">
7+
<p>Sorry, there's nothing at this address.</p>
8+
</LayoutView>
9+
</NotFound>
10+
</Router>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
<div id="context-menu-target"
3+
style="width:200px; height: 100px; background: yellow; margin-bottom: 50px;">
4+
Right click (or tap-and-hold on a touch device) for a context menu.
5+
</div>
6+
7+
<div class="alert alert-info">This context menu behavior is likely to manifest only the first time, and only on slow performing scenarios (like WebAssembly or laggy server-side connection).</div>
8+
9+
<TelerikContextMenu Selector="#context-menu-target" Data="@MenuItems"
10+
TextField="Text" SeparatorField="Separator" IconField="Icon"
11+
OnClick="@( (ContextMenuItem itm) => ClickHandler(itm) )">
12+
</TelerikContextMenu>
13+
14+
@code {
15+
List<ContextMenuItem> MenuItems { get; set; }
16+
17+
async Task ClickHandler(ContextMenuItem clickedItem)
18+
{
19+
if (!string.IsNullOrEmpty(clickedItem.CommandName))
20+
{
21+
Console.WriteLine($"The programm will now perform the {clickedItem.CommandName} operation");
22+
}
23+
}
24+
25+
protected override void OnInitialized()
26+
{
27+
28+
MenuItems = new List<ContextMenuItem>()
29+
{
30+
new ContextMenuItem
31+
{
32+
Text = "More Info",
33+
Icon = "information",
34+
CommandName = "info"
35+
},
36+
new ContextMenuItem
37+
{
38+
Separator = true
39+
},
40+
new ContextMenuItem
41+
{
42+
Text = "Advanced",
43+
Items = new List<ContextMenuItem>()
44+
{
45+
new ContextMenuItem
46+
{
47+
Text = "Delete",
48+
Icon = "delete",
49+
CommandName = "delete"
50+
},
51+
new ContextMenuItem
52+
{
53+
Text = "Report",
54+
Icon = "cancel",
55+
CommandName = "report"
56+
}
57+
}
58+
}
59+
};
60+
61+
base.OnInitialized();
62+
}
63+
64+
public class ContextMenuItem
65+
{
66+
public string Text { get; set; }
67+
public string CommandName { get; set; }
68+
public string Icon { get; set; }
69+
public bool Separator { get; set; }
70+
public List<ContextMenuItem> Items { get; set; }
71+
}
72+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<div class="alert alert-info">Scroll down to the button that opens a window and the context menu target so you can show them.</div>
2+
3+
<div class="alert alert-danger">The CSS rules depend on the app layout and will vary between projects</div>
4+
5+
<div style="height: 2000px; background: aliceblue;">I am very tall content to generate scrollbars in the layout</div>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<p>
2+
The behavior stems from the place of rendering of the popup in the DOM, which element is scrollable, and
3+
which element is focused. The Telerik popups have a default focus which is essential for accessibility and UX
4+
and browsers try to <code>scrollIntoView()</code> the focused element. That focused element is now in the popup
5+
and the browser does not correctly estimate where and what to scroll, and does not take into account the
6+
<code>position: absolute</code> that the popup has, so it usually scrolls to the top of the content.
7+
</p>
8+
<p>
9+
The solution is to control what can be scrolled and to ensure that the parent elements of the popups match the browser viewport
10+
and also match the scrollable container. In this layout, the <code>.content</code> element is the container that should get
11+
scrollbars because it holds the actual app content. So, with a bit of CSS we can make all its parent elements match the viewport
12+
size and height, so that the browser will not scroll when an absolutely positioned element gets focus.
13+
</p>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@page "/fix"
2+
3+
<style>
4+
/* set all top-level elements in the layout to height 100% so they match the viewport */
5+
html, body, #app, .page, .main {
6+
/* the two key rules to define dimensions and ensure scrollbars are not in a high level */
7+
height: 100%;
8+
overflow: hidden;
9+
/* these two rules are a common safeguard to better tighten dimensions, they may not be needed for your case */
10+
min-height: 100%;
11+
max-height: 100%;
12+
}
13+
/* define where scrollbars can appear in the layout - in a child element whose actual height
14+
still matches the viewport*/
15+
.content {
16+
/* allow scrolling of the actual app content */
17+
overflow: auto;
18+
/* height is not 100% in this layout beause it uses flex and has a header inside
19+
so we use calc() to account for the header and we take its size from the app stylesheet */
20+
height: calc(100% - 3.5rem);
21+
}
22+
</style>
23+
24+
<Issue />
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@page "/"
2+
3+
<DummyContent />
4+
5+
<WindowExample />
6+
7+
<ContextMenuExample />
8+
9+
<Explanation />
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<div style="margin: 50px;">
2+
<TelerikButton OnClick="@( () => WindowIsVisible = !WindowIsVisible )"
3+
ButtonType="@ButtonType.Button" Primary="true">
4+
Toggle window
5+
</TelerikButton>
6+
</div>
7+
8+
<TelerikWindow @bind-Visible="@WindowIsVisible" Modal="false" Height="400px" Width="600px">
9+
<WindowTitle>
10+
<strong>The Title</strong>
11+
</WindowTitle>
12+
<WindowContent>
13+
<p>I should not change the scroll position of the content. If the page scroll is not setup correctly, I can, however.</p>
14+
<Explanation />
15+
</WindowContent>
16+
<WindowActions>
17+
<WindowAction Name="Minimize"></WindowAction>
18+
<WindowAction Name="Maximize"></WindowAction>
19+
<WindowAction Name="Close"></WindowAction>
20+
</WindowActions>
21+
</TelerikWindow>
22+
23+
@code {
24+
bool WindowIsVisible { get; set; }
25+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using System;
4+
using System.Net.Http;
5+
using System.Threading.Tasks;
6+
7+
namespace popup_causes_scroll.Client
8+
{
9+
public class Program
10+
{
11+
public static async Task Main(string[] args)
12+
{
13+
var builder = WebAssemblyHostBuilder.CreateDefault(args);
14+
builder.RootComponents.Add<App>("#app");
15+
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
16+
17+
builder.Services.AddTelerikBlazor();
18+
19+
await builder.Build().RunAsync();
20+
}
21+
}
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": false,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:55337/",
7+
"sslPort": 44377
8+
}
9+
},
10+
"profiles": {
11+
"IIS Express": {
12+
"commandName": "IISExpress",
13+
"launchBrowser": true,
14+
"environmentVariables": {
15+
"ASPNETCORE_ENVIRONMENT": "Development"
16+
}
17+
},
18+
"popup_causes_scroll.Client": {
19+
"commandName": "Project",
20+
"launchBrowser": true,
21+
"environmentVariables": {
22+
"ASPNETCORE_ENVIRONMENT": "Development"
23+
},
24+
"applicationUrl": "https://localhost:5001;http://localhost:5000"
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)