Browse Source

Add focus-visible support with tests

pull/4216/head
Maksym Katsydan 6 years ago
parent
commit
6f7dac83d1
  1. 7
      src/Avalonia.Input/InputElement.cs
  2. 79
      tests/Avalonia.Input.UnitTests/InputElement_Focus.cs

7
src/Avalonia.Input/InputElement.cs

@ -158,6 +158,7 @@ namespace Avalonia.Input
private bool _isEffectivelyEnabled = true;
private bool _isFocused;
private bool _isFocusVisible;
private bool _isPointerOver;
private GestureRecognizerCollection _gestureRecognizers;
@ -427,7 +428,9 @@ namespace Avalonia.Input
/// <param name="e">The event args.</param>
protected virtual void OnGotFocus(GotFocusEventArgs e)
{
IsFocused = e.Source == this;
var isFocused = e.Source == this;
_isFocusVisible = isFocused && (e.NavigationMethod == NavigationMethod.Directional || e.NavigationMethod == NavigationMethod.Tab);
IsFocused = isFocused;
}
/// <summary>
@ -436,6 +439,7 @@ namespace Avalonia.Input
/// <param name="e">The event args.</param>
protected virtual void OnLostFocus(RoutedEventArgs e)
{
_isFocusVisible = false;
IsFocused = false;
}
@ -602,6 +606,7 @@ namespace Avalonia.Input
if (isFocused.HasValue)
{
PseudoClasses.Set(":focus", isFocused.Value);
PseudoClasses.Set(":focus-visible", _isFocusVisible);
}
if (isPointerOver.HasValue)

79
tests/Avalonia.Input.UnitTests/InputElement_Focus.cs

@ -42,5 +42,84 @@ namespace Avalonia.Input.UnitTests
Assert.Null(FocusManager.Instance.Current);
}
}
[Fact]
public void Focus_Pseudoclass_Should_Be_Applied_On_Focus()
{
using (UnitTestApplication.Start(TestServices.RealFocus))
{
var target1 = new Decorator();
var target2 = new Decorator();
var root = new TestRoot
{
Child = new StackPanel
{
Children =
{
target1,
target2
}
}
};
target1.ApplyTemplate();
target2.ApplyTemplate();
FocusManager.Instance?.Focus(target1);
Assert.True(target1.IsFocused);
Assert.True(target1.Classes.Contains(":focus"));
Assert.False(target2.IsFocused);
Assert.False(target2.Classes.Contains(":focus"));
FocusManager.Instance?.Focus(target2, NavigationMethod.Tab);
Assert.False(target1.IsFocused);
Assert.False(target1.Classes.Contains(":focus"));
Assert.True(target2.IsFocused);
Assert.True(target2.Classes.Contains(":focus"));
}
}
[Fact]
public void Control_FocusVsisible_Pseudoclass_Should_Be_Applied_On_Tab_And_DirectionalFocus()
{
using (UnitTestApplication.Start(TestServices.RealFocus))
{
var target1 = new Decorator();
var target2 = new Decorator();
var root = new TestRoot
{
Child = new StackPanel
{
Children =
{
target1,
target2
}
}
};
target1.ApplyTemplate();
target2.ApplyTemplate();
FocusManager.Instance?.Focus(target1);
Assert.True(target1.IsFocused);
Assert.False(target1.Classes.Contains(":focus-visible"));
Assert.False(target2.IsFocused);
Assert.False(target2.Classes.Contains(":focus-visible"));
FocusManager.Instance?.Focus(target2, NavigationMethod.Tab);
Assert.False(target1.IsFocused);
Assert.False(target1.Classes.Contains(":focus-visible"));
Assert.True(target2.IsFocused);
Assert.True(target2.Classes.Contains(":focus-visible"));
FocusManager.Instance?.Focus(target1, NavigationMethod.Directional);
Assert.True(target1.IsFocused);
Assert.True(target1.Classes.Contains(":focus-visible"));
Assert.False(target2.IsFocused);
Assert.False(target2.Classes.Contains(":focus-visible"));
}
}
}
}

Loading…
Cancel
Save