using System; using System.IO; using System.Linq; using System.Reflection; using AtomUI; using AtomUI.Controls; using AtomUI.Controls.Commons; using AtomUI.Controls.Primitives; using AtomUI.Desktop.Controls.DesignTokens; using AtomUI.Theme; using AtomUI.Theme.Configuration; using AtomUI.Theme.Resources; using AtomUI.Theme.Schema; using Avalonia; using Avalonia.Animation; using Avalonia.Controls; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Media; using Avalonia.Threading; using Avalonia.VisualTree; using Shouldly; using Xunit; using AtomUILineEdit = AtomUI.Desktop.Controls.LineEdit; using AtomUIEmbeddedTextBox = AtomUI.Desktop.Controls.EmbeddedTextBox; using AtomUISearchEdit = AtomUI.Desktop.Controls.SearchEdit; using AtomUITextArea = AtomUI.Desktop.Controls.TextArea; using AtomUITextBox = AtomUI.Desktop.Controls.TextBox; using AtomUIScrollViewer = AtomUI.Desktop.Controls.ScrollViewer; using AvaloniaWindow = Avalonia.Controls.Window; namespace AtomUI.Desktop.Controls.Tests.Input; public class TextBoxVisualStateTests { static TextBoxVisualStateTests() { AvaloniaTestApp.EnsureInitialized(); } [Fact] public void Disabled_TextBox_Uses_Disabled_Text_Foreground() { var textBox = new AtomUITextBox { Width = 160, Text = "3", IsEnabled = false, IsMotionEnabled = false }; ShowInWindow(textBox, () => { var scrollViewer = textBox.GetVisualDescendants() .OfType() .Single(item => item.Name == "ScrollViewer"); BrushShouldHaveSameColor( scrollViewer.Foreground, GetThemeResource(SharedTokenKind.ColorTextDisabled)); }); } [Fact] public void TextBox_InnerBoxDecorator_Uses_TextBox_Border_Tokens_For_Default_Hover_And_Focus() { var textBox = new AtomUITextBox { Width = 180, IsMotionEnabled = false }; ShowInWindow(textBox, () => { var border = FindTemplatePart(textBox, "InnerBoxDecorator"); var expectedThickness = GetTextBoxTokenResource("BorderThickness"); var defaultBorder = GetTextBoxTokenResource("BorderColor"); var hoverBorder = GetTextBoxTokenResource("HoverBorderColor"); var activeBorder = GetTextBoxTokenResource("ActiveBorderColor"); var activeShadow = GetTextBoxTokenResource("ActiveShadow"); textBox.BorderThickness.ShouldBe(expectedThickness); border.BorderThickness.ShouldBe(expectedThickness); BrushShouldHaveSameColor(border.BorderBrush, defaultBorder); SetPseudoClass(textBox, StdPseudoClass.PointerOver, true); Dispatcher.UIThread.RunJobs(); border.BorderThickness.ShouldBe(expectedThickness); BrushShouldHaveSameColor(border.BorderBrush, hoverBorder); textBox.Focus(); Dispatcher.UIThread.RunJobs(); textBox.IsFocused.ShouldBeTrue(); border.BorderThickness.ShouldBe(expectedThickness); BrushShouldHaveSameColor(border.BorderBrush, activeBorder); border.BoxShadow.ShouldBe(activeShadow); }); } [Fact] public void TextBox_Uses_Customizable_SizeType_Contract_And_Control_Shared_Token_Resources() { typeof(ICustomizableSizeTypeAware).IsAssignableFrom(typeof(AtomUITextBox)).ShouldBeTrue(); var property = typeof(AtomUITextBox).GetProperty( "SizeType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); property.ShouldNotBeNull(); property!.PropertyType.ShouldBe(typeof(CustomizableSizeType)); var field = typeof(AtomUITextBox).GetField( "SizeTypeProperty", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); field.ShouldNotBeNull(); field!.FieldType.ShouldBe(typeof(StyledProperty)); var textBoxTokenType = typeof(AtomUITextBox).Assembly.GetType("AtomUI.Desktop.Controls.TextBoxToken"); textBoxTokenType.ShouldNotBeNull(); textBoxTokenType! .GetField("ScopeProvider", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy) .ShouldBeNull(); var source = ReadRepoFile("src/AtomUI.Desktop.Controls/Input/Themes/TextBoxTheme.axaml"); source.ShouldContain("SharedTokenResource FontSize"); source.ShouldContain("themeResources:ControlTokenScope.Identity="); source.ShouldNotContain("TokenSharedTokenResource"); } [Fact] public void TextBox_Uses_Custom_SizeType_For_Template_Owned_Padding_Without_Extra_State() { var property = typeof(AtomUITextBox).GetProperty( "IsCustomPadding", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); property.ShouldBeNull(); var field = typeof(AtomUITextBox).GetField( "IsCustomPaddingProperty", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); field.ShouldBeNull(); } [Fact] public void EmbeddedTextBox_Is_Internal_TextBox_For_Template_Owned_Input_Chrome() { typeof(AtomUITextBox).IsAssignableFrom(typeof(AtomUIEmbeddedTextBox)).ShouldBeTrue(); typeof(ICustomizableSizeTypeAware).IsAssignableFrom(typeof(AtomUIEmbeddedTextBox)).ShouldBeTrue(); var embeddedTextBox = new AtomUIEmbeddedTextBox { Width = 160, Text = "embedded", IsEnabled = false }; ShowInWindow(embeddedTextBox, () => { embeddedTextBox.SizeType.ShouldBe(CustomizableSizeType.Custom); embeddedTextBox.Padding.ShouldBe(new Thickness(0)); embeddedTextBox.BorderThickness.ShouldBe(new Thickness(0)); embeddedTextBox.IsCustomFontSize.ShouldBeTrue(); embeddedTextBox.IsAllowClear.ShouldBeFalse(); embeddedTextBox.IsEnableRevealButton.ShouldBeFalse(); var border = FindTemplatePart(embeddedTextBox, "InnerBoxDecorator"); border.BorderThickness.ShouldBe(new Thickness(0)); BrushShouldHaveSameColor(border.Background, Brushes.Transparent); BrushShouldHaveSameColor(border.BorderBrush, Brushes.Transparent); }); } [Fact] public void EmbeddedTextBox_Theme_Suppresses_Own_Disabled_Chrome() { var source = ReadRepoFile("src/AtomUI.Desktop.Controls/Input/Themes/EmbeddedTextBoxTheme.axaml"); source.ShouldContain("TargetType=\"atom:EmbeddedTextBox\""); source.ShouldContain(""); source.ShouldContain(""); source.ShouldContain(""); source.ShouldContain(""); source.ShouldContain("