From ed6c4fc877b1de8433083ff11ff92def7c8ffa50 Mon Sep 17 00:00:00 2001 From: Kristen Schau <47155823+krschau@users.noreply.github.com> Date: Tue, 27 Feb 2024 17:26:25 -0500 Subject: [PATCH] use placeholder in lieu of header if available --- common/Renderers/AccessibleChoiceSet.cs | 44 +++++++++++++++++++ .../Views/AccountsPage.xaml.cs | 1 + .../Services/AdaptiveCardRenderingService.cs | 1 + .../Models/RepositoryProvider.cs | 1 + 4 files changed, 47 insertions(+) create mode 100644 common/Renderers/AccessibleChoiceSet.cs diff --git a/common/Renderers/AccessibleChoiceSet.cs b/common/Renderers/AccessibleChoiceSet.cs new file mode 100644 index 0000000000..0bc9102f41 --- /dev/null +++ b/common/Renderers/AccessibleChoiceSet.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Linq; +using AdaptiveCards.ObjectModel.WinUI3; +using AdaptiveCards.Rendering.WinUI3; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Automation; +using Microsoft.UI.Xaml.Controls; + +namespace DevHome.Common.Renderers; + +public class AccessibleChoiceSet : IAdaptiveElementRenderer +{ + public UIElement Render(IAdaptiveCardElement element, AdaptiveRenderContext context, AdaptiveRenderArgs renderArgs) + { + var renderer = new AdaptiveChoiceSetInputRenderer(); + + if (element is AdaptiveChoiceSetInput choiceSet) + { + // Label property corresponds to the Header dependency property on the ComboBox. + var header = choiceSet.Label; + var placeholderText = choiceSet.Placeholder; + + // If there is no Header, there will not be an accessible Name. + // Use the Placeholder text as the accessible Name if possible. + if (string.IsNullOrEmpty(header) && !string.IsNullOrEmpty(placeholderText)) + { + var result = renderer.Render(choiceSet, context, renderArgs); + if (result is StackPanel stackPanel) + { + var comboBox = stackPanel.Children.First() as ComboBox; + if (comboBox != null) + { + AutomationProperties.SetName(comboBox, placeholderText); + return stackPanel; + } + } + } + } + + return renderer.Render(element, context, renderArgs); + } +} diff --git a/settings/DevHome.Settings/Views/AccountsPage.xaml.cs b/settings/DevHome.Settings/Views/AccountsPage.xaml.cs index 85bab4c29e..cb9192c375 100644 --- a/settings/DevHome.Settings/Views/AccountsPage.xaml.cs +++ b/settings/DevHome.Settings/Views/AccountsPage.xaml.cs @@ -156,6 +156,7 @@ private async Task ConfigureLoginUIRenderer(AdaptiveCardRenderer renderer) // Add custom Adaptive Card renderer for LoginUI as done for Widgets. renderer.ElementRenderers.Set(LabelGroup.CustomTypeString, new LabelGroupRenderer()); + renderer.ElementRenderers.Set("Input.ChoiceSet", new AccessibleChoiceSet()); var hostConfigContents = string.Empty; var hostConfigFileName = (ActualTheme == ElementTheme.Light) ? "LightHostConfig.json" : "DarkHostConfig.json"; diff --git a/tools/Dashboard/DevHome.Dashboard/Services/AdaptiveCardRenderingService.cs b/tools/Dashboard/DevHome.Dashboard/Services/AdaptiveCardRenderingService.cs index 34b2d4e2ec..11ef7ab546 100644 --- a/tools/Dashboard/DevHome.Dashboard/Services/AdaptiveCardRenderingService.cs +++ b/tools/Dashboard/DevHome.Dashboard/Services/AdaptiveCardRenderingService.cs @@ -77,6 +77,7 @@ private async Task ConfigureWidgetRenderer() { // Add custom Adaptive Card renderer. _renderer.ElementRenderers.Set(LabelGroup.CustomTypeString, new LabelGroupRenderer()); + _renderer.ElementRenderers.Set("Input.ChoiceSet", new AccessibleChoiceSet()); // A different host config is used to render widgets (adaptive cards) in light and dark themes. await UpdateHostConfig(); diff --git a/tools/SetupFlow/DevHome.SetupFlow/Models/RepositoryProvider.cs b/tools/SetupFlow/DevHome.SetupFlow/Models/RepositoryProvider.cs index 87137cd410..099b4ea8aa 100644 --- a/tools/SetupFlow/DevHome.SetupFlow/Models/RepositoryProvider.cs +++ b/tools/SetupFlow/DevHome.SetupFlow/Models/RepositoryProvider.cs @@ -183,6 +183,7 @@ private async Task ConfigureLoginUIRenderer(AdaptiveCardRenderer renderer, Eleme // Add custom Adaptive Card renderer for LoginUI as done for Widgets. renderer.ElementRenderers.Set(LabelGroup.CustomTypeString, new LabelGroupRenderer()); + renderer.ElementRenderers.Set("Input.ChoiceSet", new AccessibleChoiceSet()); var hostConfigContents = string.Empty; var hostConfigFileName = (elementTheme == ElementTheme.Light) ? "LightHostConfig.json" : "DarkHostConfig.json";