Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Adding a Expander Control to the set of WinUI controls. #3279

Open
eduardoaguacate opened this issue Sep 11, 2020 · 88 comments
Open
Assignees
Labels
feature proposal New feature proposal team-Controls Issue for the Controls team wct

Comments

@eduardoaguacate
Copy link
Contributor

eduardoaguacate commented Sep 11, 2020

Proposal: WinUI Expander Control

A spec has been opened with a PR for this issue. Feel free to continue general discussion in this proposal!

Summary

Throughout Windows, different expander controls are used by Windows Security, Settings, Photos, Paint 3D, the Notification Center, 3D Viewer, Toasts and the UWP Onedrive app. There’s currently no consistent "Windows" way of addressing this common UX pattern. An Expander control is motivated by both its use in many app scenarios and achieving parity with WPF.

Rationale

  • There should be a built-in and consistent Fluent way to expand and collapse content.
  • Expander scenarios exist across many surfaces that are not aligned in behavior and style, including being Narrator-friendly, keyboard controls, animations, designs, and high contrast changes.

Scope

Capability Priority
Provide consistent expander behavior across WinUI apps Must
Expand in size (pushing other content) and collapse based on user interaction with the control Must
Support controls like Button, ToggleSwitch in the unexpanded and expanded content Must
Support Expanding in all 4 directions Should*
Support modifying all content (including the header) in expanded state Could
Support expanding an InfoBar (open question on implementation) Could
Include "accordion behavior" logic between Expanders Won't
Be light dismissible Won't

*The v1 Expander could be scoped to only expand in the downwards direction, with default down and ExpandDirection added later.

Important Notes

Proposed API

Public enum ExpandDirection 
{ 
Down = 0 
Up = 1 
Left = 2 
Right = 3 
} 

public class Expander : ContentControl 
{ 
Expander(); 

public object Header {get;set;} 
public DataTemplate HeaderTemplate { get;set; } 
public DataTemplate HeaderTemplateSelector {get;set;} 

public static readonly DependencyProperty HeaderProperty; 
public static readonly DependencyProperty HeaderTemplateProperty; 
public static readonly DependencyProperty HeaderTemplateSelectorProperty {get;} 

public bool IsExpanded { get;set} 
public ExpandDirection ExpandDirection { get;set;} 

protected virtual void OnExpanded(); 
protected virtual void OnCollapsed();

public event Expanded; 
public event Collapsed; 

public static readonly DependencyProperty IsExpandedProperty; 
public static readonly DependencyProperty ExpandDirectionProperty; 
} 

Visual States:  
ExpandStates: Expanded/Collapsed 

Accessibility: 
Support Expand/Collapse pattern (IExpandCollapseProvider) 

Expander Controls Elsewhere

Examples of Expander Scenarios

expandcontrol-4 1
expandcontrol-2

Open Questions

  • In discussion with the WinUI team, it was brought up that a V1 scoped to expand downward would shorten development time and make Expander available for developers sooner (as the scenarios for Expander thus far have all been downward), and a planned V2 could add ExpandDirection soon after. In your apps, are there any scenarios where Expander would need to expand in directions other than downward?

  • How should Expander work with InfoBar? Adding expanding functionality to InfoBar? Putting InfoBar as the content of an Expander? The reverse?

@eduardoaguacate eduardoaguacate added the feature proposal New feature proposal label Sep 11, 2020
@msft-github-bot msft-github-bot added this to Freezer in Feature tracking Sep 11, 2020
@msft-github-bot msft-github-bot added the needs-triage Issue needs to be triaged by the area owners label Sep 11, 2020
@StephenLPeters StephenLPeters added team-Controls Issue for the Controls team and removed needs-triage Issue needs to be triaged by the area owners labels Sep 11, 2020
@StephenLPeters StephenLPeters assigned YuliKl, gabbybilka and kat-y and unassigned YuliKl Sep 11, 2020
@robloo
Copy link
Contributor

robloo commented Sep 13, 2020

Expander is very useful and I've been using the Windows Community Toolkit version since it was added. I wouldn't re-invent the wheel too much though, just porting over the code from the toolkit would be perfect for version 1.0 in my opinion.

Another example: the ColorPicker with it's 'MoreButton' could use this.

@kat-y
Copy link

kat-y commented Sep 21, 2020

Thanks so much for submitting this proposal! I'm going to make some edits, including differentiating between what I think are true Expander scenarios and what are more like Flyout/MenuFlyout uses.

@kat-y
Copy link

kat-y commented Sep 24, 2020

I've updated this proposal to include more details on the scope, a proposed API, and the following open question.

  • Do we need to support ExpandDirection in a v1 Expander? Are there common app scenarios where Expander would need to expand in directions other than downward?

Would love feedback on how these fit or don't fit with your use cases for Expander!

@mdtauk
Copy link
Contributor

mdtauk commented Sep 24, 2020

I've updated this proposal to include more details on the scope, a proposed API, and the following open question.

  • Do we need to support ExpandDirection in a v1 Expander? Are there common app scenarios where Expander would need to expand in directions other than downward?

Would love feedback on how these fit or don't fit with your use cases for Expander!

It does seem like a basic function of the control

@kat-y
Copy link

kat-y commented Sep 24, 2020

It does seem like a basic function of the control

@mdtauk do you see ExpandDirection other than downward being a common app scenario? The examples of Expander behaviors that I see are far more often expanding downwards - I would definitely like Expander to have ExpandDirection but is it necessary in a v1?

@robloo
Copy link
Contributor

robloo commented Sep 24, 2020

Yes, we need expand direction. There are many cases for using it and it would be an unnecessary breaking change to the control template after a v1 release to add it. The Expander API hasn't changed much since WPF and the proposal here has all the necessary properties/events/methods already. I would just implement it all in one shot and we can be done with this control. Design-wise the UWP Community Toolkit made the necessary changes to better work with touch. I think we have all the pieces and there is no need to re-invent anything.

Edit: The community toolkit also has a ContentOverlay property. That might be something to skip in a V1.

@YuliKl YuliKl removed their assignment Sep 24, 2020
@kat-y
Copy link

kat-y commented Sep 24, 2020

Yes, we need expand direction. There are many cases for using it and it would be an unnecessary breaking change to the control template after a v1 release to add it.

@robloo Could you elaborate on how this would be a breaking change? My understanding is we could avoid it being breaking with V1 having downward expansion, and V2 could add ExpandDirection and default to downward.

@mdtauk
Copy link
Contributor

mdtauk commented Sep 24, 2020

It does seem like a basic function of the control

@mdtauk do you see ExpandDirection other than downward being a common app scenario? The examples of Expander behaviors that I see are far more often expanding downwards - I would definitely like Expander to have ExpandDirection but is it necessary in a v1?

Chat apps which load new list content from the bottom up being one of them maybe.

Beyond the very basic essential:

  • IsCollapsed
  • IsExpanding
  • IsExpanded
  • IsCollapsing

As well as IsEnabled

The next core thing is where to expand to.

  • ExpandUp
  • ExpandDown
  • ExpandLeft
  • ExpandRight

@kat-y
Copy link

kat-y commented Sep 24, 2020

Chat apps which load new list content from the bottom up being one of them maybe.

@mdtauk I don't fully understand what you mean with this chat apps example - could you elaborate?
As for the properties - the proposed API is based off the WPF Expander so I think IsExpanded and ExpandDirection would cover them. What would IsEnabled be used for - is there an app scenario where you'd want to disable an Expander?

@robloo
Copy link
Contributor

robloo commented Sep 24, 2020

Another example I've used in the past are secondary, editable properties that should usually be hidden. These are shown at the bottom of an editor only when clicking an 'options' button and the expander opens upwards. It's really just up to the design you are going for. There are many useful cases for expanding different directions and it seems unnecessary to artificially restrict this especially when past convention is so strong. I don't think any of this would be too difficult in a V1 of the control especially since all the problems have already been solved in the community toolkit and WPF.

@robloo Could you elaborate on how this would be a breaking change? My understanding is we could avoid it being breaking with V1 having downward expansion, and V2 could add ExpandDirection and default to downward.

https://github.com/windows-toolkit/WindowsCommunityToolkit/blob/master/Microsoft.Toolkit.Uwp.UI.Controls/Expander/Expander.xaml

I suppose if you are very careful in designing the template and visual states it is possible to make it non-breaking. However, to do that you really need to design the functionality anyway so you might as well implement it. This is all fairly basic and there is no reason for a V2 plan from the get-go on this control.

I know its enticing to re-invent the wheel. But please keep it so people porting apps from WPF to WinUI can do it without anything but absolutely necessary code changes. WinUI needs to start correcting some of the mistakes with UWP.

@robloo
Copy link
Contributor

robloo commented Sep 24, 2020

What would IsEnabled be used for - is there an app scenario where you'd want to disable an Expander?

@mdtauk Is correct, this needs to support IsEnabled as well. Disabling controls is pretty strong convention anytime there is the possibility of input or state change. Please don't make us defend that.

@JustABearOz
Copy link

In the screenshots above, windows security has an expander for the antivirus section as well as the left navigation menu. This shows a very realistic use of the expander in more than one direction that a lot of apps would need to support. My vote is for supporting multiple directions in V1.

@kat-y
Copy link

kat-y commented Sep 25, 2020

@robloo

Another example I've used in the past are secondary, editable properties that should usually be hidden. These are shown at the bottom of an editor only when clicking an 'options' button and the expander opens upwards.

Could you elaborate with a screenshot or specific app where this happens so I can understand the scenario more? I can think of editors where a options button opens a popup with more buttons, but in the ones I'm familiar with the other content isn't pushed upwards - a popup/flyout behavior rather than an expansion.

I suppose if you are very careful in designing the template and visual states it is possible to make it non-breaking. However, to do that you really need to design the functionality anyway so you might as well implement it. This is all fairly basic and there is no reason for a V2 plan from the get-go on this control.
I know its enticing to re-invent the wheel. But please keep it so people porting apps from WPF to WinUI can do it without anything but absolutely necessary code changes.

I agree with you that porting apps from WPF to WinUI should be as smooth as possible! In discussion with the WinUI team, it was brought up that a V1 scoped to expand downward would shorten development time and make Expander available for developers sooner (as the scenarios for Expander thus far have all been downward), and a planned V2 could add ExpandDirection soon after. (I'll edit the open question to have this additional context) This is why I'm hoping to understand if there are specific use cases developers have for non-downward Expander! 😄

Disabling controls is pretty strong convention anytime there is the possibility of input or state change. Please don't make us defend that.

Thanks for explaining this, it totally makes sense that disabling the state change is a desired feature for this kind of control!

@kat-y
Copy link

kat-y commented Sep 25, 2020

In the screenshots above, windows security has an expander for the antivirus section as well as the left navigation menu. This shows a very realistic use of the expander in more than one direction that a lot of apps would need to support. My vote is for supporting multiple directions in V1.

@JustABearOz I think the left navigation menu is a NavigationView, actually. 😃 I agree that the antivirus section is an Expander scenario, in this case expanding downwards. Would love to know any specific use cases you have for non-downward Expander!

@JustABearOz
Copy link

@kat-y Ok, that takes away a need for left/right, but 2 examples in windows that seem to expand up that could easily apply to apps:
1: The screenshot above with the quick actions menu. Pretty sure that expands up.
2: In windows, the popup calendar form the system tray has a section which expand up to show agenda/appointments.

Is it possible to support Up/Down for V1 instead of just Down?

@kat-y
Copy link

kat-y commented Sep 25, 2020

1: The screenshot above with the quick actions menu. Pretty sure that expands up.

@JustABearOz thanks so much for bringing up these examples! For 1: I think this is an interesting edge case - the expansion is 'downwards' from the 'header' (the expand button), but the control itself is positioned at the bottom of the surface so the header (and the expanded content) has to 'shift' upwards (otherwise it would run off the screen!). Seems like a good way to handle having an expanding item at the 'bottom' of an app, do you agree?

2: In windows, the popup calendar form the system tray has a section which expand up to show agenda/appointments.
Is it possible to support Up/Down for V1 instead of just Down?

I agree with you, this is a scenario where the header is at the bottom of the area and expands up! In this case the calendar's expander (and the popup as a whole) is tied to the taskbar - have you encountered scenarios in apps where expanders have a similar tied positioning that necessitates upward expansion?

@robloo
Copy link
Contributor

robloo commented Sep 25, 2020

@kat-y I mean no offense but I feel like we are having to re-explain things that were known 15 years ago. I don't understand why you are asking us to give examples of expand direction in real-world usage. I expect internally you have to take this to spec review and defend it to management. But the explanation can simply be (1) you need to empower users to achieve their design targets, it's not up to Microsoft to say what is/is-not possible to do with controls it's up to app developers/designers to discover what is best for their use-case (a critical concept for look-less controls) (2) Most importantly, this is not a new idea at all. You are copying over an existing API in this area and need to maintain app compatiblity. Again, if this was a new idea I would understand more why we have to defend it -- it's good to make sure features are useful before investing the time in them.

Aside from the header there are literally two properties in this control and if it was C# I could write it in a few hours using the WCT base. We will spend more man-hours just talking about it than implementing it as it exists today in WPF/WCT.

@kat-y
Copy link

kat-y commented Sep 30, 2020

Thanks for the priority order @mdtauk!

I've added a new open question:

  • How should Expander work with InfoBar? Adding expanding functionality to InfoBar? Putting InfoBar as the content of an Expander? The reverse?

@mdtauk
Copy link
Contributor

mdtauk commented Sep 30, 2020

I would imagine it would replace the content, but I think those designing the information bar should provide a design spec for a collapsible bar, which the expander designers can look at.

It's a conversation to be had

@stmoy
Copy link
Contributor

stmoy commented Sep 30, 2020

There's a bunch of great conversation here! On the topic of animations...

It sounds like ElementAnimator is too much for animating Expander, and that ExpandTransition and CollapseTransition would suffice.

Agree that ElementAnimator is too much for animating Expander. It might work if everything was in an ItemsRepeater, but ElementAnimator doesn't work outside of ItemsRepeater yet so we'd need to figure that out.

I like the idea of having an ExpandTransition and CollapseTransition in theory, but we've gotten a ton of feedback that the Transition APIs are good in theory but less good in practice because they are not customizable, they are generally tightly coupled to the controls in which they are used, and I don't think they can be built in WinUI 2.x series since they rely on OS hooks. Since these specific transitions don't exist, I'd prefer to explore other options than adding to our collection of ThemeTransition APIs.

On top of all of that, the general area of "layout animations" where content moves as a result of new UI elements entering/growing/shrinking/leaving the page are not well supported in Xaml as a platform today. Fixing this will also require WinUI 3, but isn't on the immediate roadmap.

For Expander in particular, I think the proper course of action will likely end up being:

  1. Hard-code the grow/shrink animation in the Expander code (and consider including an API to turn it off - though I don't personally think one is necessary)
  2. Provide guidance to app developers about how to animate content around the Expander so that the content below the Expander slides down rather than "jumps" down

I don't think (2) can be solved generally without "layout animations" but can probably be worked around using RepositionThemeAnimation on the content below the Expander.

@ranjeshj
Copy link
Contributor

ranjeshj commented Oct 1, 2020

@stmoy We could use PopInThemeAnimation for (1) if we wanted to go with the existing ones.

@kat-y
Copy link

kat-y commented Oct 2, 2020

This proposal has been approved for spec writing.

As part of discussion with the WinUI team, we determined that Expander could be scoped to support ExpandDirection for up/down expansion in V1. This covers the scenarios we've seen for Expander and lays groundwork to potentially add left/right expansion in the future.

Please feel encouraged to continue discussion here, and more detailed discussion will occur on the Spec and the associated PR once it's available. Would especially love to hear your thoughts on this open question:

  • How should Expander work with InfoBar? Adding expanding functionality to InfoBar? Putting InfoBar as the content of an Expander? The reverse?

@gabbybilka
Copy link
Member

For InfoBar, I think I need to open a separate proposal to dive into what specifically it needs and how it can take advantage of this Expander control. Here's some of my first thoughts:

  • An InfoBar needs to customize the header and content/pane of the Expander control. The InfoBar should show a "cut-off" message in the header when collapsed and a full message in the expanded content/pane when opened.
  • An InfoBar doesn't have to allow truncation and the option should be there for the developer to choose the current wrapping behavior if needed via a "shouldTruncate" property.
  • An InfoBar could/should "become" an Expander if the content no longer fits on a single line and shouldTruncate is set to true. Implementing this and understanding when exactly to add the expanding behavior is where it gets tricky 😊 MessageBar mitigates this via their isMultiline property but further thought needs to go into this area.

I think we can also look into other controls in WinUI currently that may benefit from this Expander behavior.

Some initial comps for truncating InfoBar:
Expand/collapse

For implementation, my initial thoughts are that an InfoBar should derive from an Expander and not be nested inside Expander's content. Thoughts?

@mdtauk
Copy link
Contributor

mdtauk commented Oct 2, 2020

I think we can also look into other controls in WinUI currently that may benefit from this Expander behavior.

Some initial comps for truncating InfoBar:
Expand/collapse

I think the Expander may need to be able to separate the Chevron Button from the Content being expanded.

image
Notifications do this

It would also allow the InformationBar control to integrate it's Expander.

If you do separate it, does that become a behaviour/property? So if you specify a UI Element or Button to this property, the Expander Header does not display it's Button?

For implementation, my initial thoughts are that an InfoBar should derive from an Expander and not be nested inside Expander's content. Thoughts?

If the Expander can't separate the Content and Header from the Toggle/Disclose Button - then that would require more work for the InformationBar to implement.

The Expander control should be as flexible as possible specifically for integrating into various other Controls going forward, as well as for use in the Windows Shell

@kat-y
Copy link

kat-y commented Oct 29, 2020

I've added initial info to the Expander spec and opened a PR - please feel free to continue spec discussion there! It's PR 100 on the spec repo 😄

@ranjeshj ranjeshj moved this from Back Burner to Front Burner in Feature tracking Nov 2, 2020
@ghost ghost added this to Spec in progress in API review status Nov 2, 2020
@robloo
Copy link
Contributor

robloo commented Dec 31, 2020

There is a need in some cases to prevent the expander from expanding/collapsing. However, it is very difficult to implement this correctly with the current control even in WPF. In order to support this I propose adding two things:

  1. PreviewExpanded/PreviewCollapsed events that allow cancelling the operation
  2. A new property IsPinned could be added to pin or lock the expander in the current state until it is unpinned

@mdtauk
Copy link
Contributor

mdtauk commented Feb 4, 2021

Why is the expander using so much padding top and bottom?

image

and not closer in line with the ComboBox and DropDownButton controls?

image

@robloo
Copy link
Contributor

robloo commented Jul 17, 2021

Shouldn't this be closed?

@michael-hawker
Copy link
Collaborator

@robloo if it is, a follow-on issue for Left/Right support should be opened which is dependent on #546

@Jay-o-Way
Copy link
Contributor

Is this still an issue ? /needinfo

@SnowyWreath
Copy link

Can we get an update on the roadmap for Left and Right ExpanderDirection? Windows Community Toolkit v8.0 was released yesterday, removing its Expander control because it is now part of WinUI. This feels premature, because the toolkit control offers Left/Right expansion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature proposal New feature proposal team-Controls Issue for the Controls team wct
Projects
API review status
Spec in progress
Feature tracking
Front Burner
Development

No branches or pull requests