Microsoft-ui-xaml: Proposal: Adding a Expander Control to the set of WinUI controls.

Created on 11 Sep 2020  路  82Comments  路  Source: microsoft/microsoft-ui-xaml

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鈥檚 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?
feature proposal team-Controls

Most helpful comment

Welcome to the WinUI project @kat-y - Xaml has a long history but can be a little quirky to those new to it. While WinUI is an opportunity to rethink how things work, in this case, expander is a relatively simple control and so a simple move from WPF to WinUI should suffice.

@robloo I disagree with your assertion that there is no need to re-engineer the XAML control template. WPF AFAIR has a number of chrome like elements which would be out of place in WinUI/Fluent.

Handling the Chevron and touch target sizes, as well as using the font scaling sizes. The Chevron should be easy to remove, or to add.

image
This example has a chevron in line with the text.

image
This example has no chevron at all

image
This example has a preceding side facing chevron


As for the implementation, there should be an animated transition when opening and closing, unless the user has turned off animations, then it just switches states.

All 82 comments

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.

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.

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!

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

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?

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.

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.

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

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?

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.

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.

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.

@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!

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!

@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?

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?

@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.

Thanks @robloo for the input, I'm reaching out to the WinUI team to discuss how we can make these proposals more robust initially when they exist in other third-party libraries like the Toolkit. I definitely think it should be something part of the issue template to call out existing examples.

FYI @ranjeshj @ryandemopoulos @stmoy

@robloo Thank you for being honest with me! I understand that app developers should be able to determine what fits their use-case best, and that app compatibility is important. I'm hoping that discussion with @michael-hawker and the WinUI team will help us move forward productively in scoping Expander!

Previously I didn't have any concrete examples of Expanders being used in non-downward direction. I will bring any examples from the WinUI community (including the calendar flyout that @justABearOz pointed out) and any that I learn from Michael to discussions with the WinUI Team as evidence for keeping ExpandDirection in v1 of Expander.

I've updated the proposal with a list of Expander controls I'm aware of - let me know if I've missed something.

I've taken a look at both the WPF source code and WCT source code. I'm confident this can be implemented in WinUI in a few hours as well. The control should follow the WCT implementation from what I've seen although the ContentOverlay property probably should be renamed or left out of V1.

WPF:
https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/Themes/XAML/Expander.xaml
https://github.com/dotnet/wpf/blob/master/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Expander.cs

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

As both of these sources are from Microsoft and licensed MIT they should be the base, don't start from zero. Xamarin Forms does not align with the concepts of WPF->WinUI so should probably be disregarded (there is no additional functionality either). The 3rd party solutions also don't have any groundbreaking new ideas from what I've seen. This control has largely stood the test of time.

@robloo Thank you for being honest with me! I understand that app developers should be able to determine what fits their use-case best, and that app compatibility is important. I'm hoping that discussion with @michael-hawker and the WinUI team will help us move forward productively in scoping Expander!

Previously I didn't have any concrete examples of Expanders being used in non-downward direction. I will bring any examples from the WinUI community (including the calendar flyout that @JustABearOz pointed out) and any that I learn from Michael to discussions with the WinUI Team as evidence for keeping ExpandDirection in v1 of Expander.

Well, my point is there really shouldn't be too many discussions about this. I'm choosing to voice my frustrations here as this control is a perfect example. The new pager control or bread crumb controls do need more oversight and it's important to follow the process. However, the overhead of a large process is showing through here and again, you will spend far more man-hours doing non value-added paperwork and discussions that just implementing the control from WCT. I've also yet to see the WinUI team use other, prior work which is somewhat of a concern. There is no need to re-engineer the XAML control template.

Welcome to the WinUI project @kat-y - Xaml has a long history but can be a little quirky to those new to it. While WinUI is an opportunity to rethink how things work, in this case, expander is a relatively simple control and so a simple move from WPF to WinUI should suffice.

@robloo I disagree with your assertion that there is no need to re-engineer the XAML control template. WPF AFAIR has a number of chrome like elements which would be out of place in WinUI/Fluent.

Handling the Chevron and touch target sizes, as well as using the font scaling sizes. The Chevron should be easy to remove, or to add.

image
This example has a chevron in line with the text.

image
This example has no chevron at all

image
This example has a preceding side facing chevron


As for the implementation, there should be an animated transition when opening and closing, unless the user has turned off animations, then it just switches states.

As for the implementation, there should be an animated transition when opening and closing, unless the user has turned off animations, then it just switches states.

I was just about to ask about animations. Should there be a way to disable them for the control, e.g. in scenarios where animating layouts would be too expensive? Not all users/developers want animations for such things as it might feel a bit to unresponsive or just not wanted (e.g. TreeView). Having to not retemplate the control to customize that point might be better. Another thing that could be customizable is the animation duration, in some cases short animations are better then longer ones.

Thanks for all the great discussions. some thoughts

  • We will need to update the template as @mdtauk mentions to account for new design as well as opportunities to reduce the elements/improve performance if possible.
  • IsEnabled is inherited from Control, so I would expect that to work.

As for the implementation, there should be an animated transition when opening and closing, unless the user has turned off animations, then it just switches states.

I was just about to ask about animations. Should there be a way to disable them for the control, e.g. in scenarios where animating layouts would be too expensive? Not all users/developers want animations for such things as it might feel a bit to unresponsive or just not wanted (e.g. TreeView). Having to not retemplate the control to customize that point might be better. Another thing that could be customizable is the animation duration, in some cases short animations are better then longer ones.

I believe some controls have a Transition property that could be assigned to. So if a non-animated storyboard was included as a resource, it could be applied and that handles that without any retemplating.

You would have to override the transition when the system setting turns animations off.

UIElement.Transitions?
https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.uielement.transitions?view=winrt-19041

Also with the IsEnabled property, there needs to be a Disabled state. Should there be a Disabled Expanded, and Disabled Collapsed, or is Disabled always collapsed?

Interesting point about animations. We turn off all animations with the system setting, but I don't think we expose knobs to turn off animations other than by re-templating currently.

Interesting point about animations. We turn off all animations with the system setting, but I don't think we expose knobs to turn off animations other than by re-templating currently.

I believe you could add a Style that overwrites the Transition collection with null in the case that you want to turn animations off, assuming there is a Transition collection to overwrite.

Including an ExpandTransition and CollapseTransition, that can use the direction set by the control's property - which could allow the dev to set the transition for each.

I like the idea, but I don't think there is a way today to create custom theme transitions which would limit the ability to customize. This would allow easily disable it though by removing it.

Also with the IsEnabled property, there needs to be a Disabled state. Should there be a Disabled Expanded, and Disabled Collapsed, or is Disabled always collapsed?

Why not mirror the TreeView control where you can use the IsExpanded and IsEnabled properties to create whatever combination you need of the two? If disabled expanded works best in some case, that can be done. If you need disabled collapsed, that is possible too this way.

@robloo I disagree with your assertion that there is no need to re-engineer the XAML control template. WPF AFAIR has a number of chrome like elements which would be out of place in WinUI/Fluent.

@mdtauk Well, my recommendation was we "should follow the WCT implementation" here: https://docs.microsoft.com/en-us/windows/communitytoolkit/controls/expander. The design changes to adapt to touch and a more modern interface were already made. Of course no one can do designs as good as you so I'm sure there is room for improvement. Still changing the 'design' wouldn't require re-engineering the template to support all expand directions. WCT should be the base and then if we have new styling to apply, very well, it can be done quickly but not from scratch.

@robloo I disagree with your assertion that there is no need to re-engineer the XAML control template. WPF AFAIR has a number of chrome like elements which would be out of place in WinUI/Fluent.

@mdtauk Well, my recommendation was we "should follow the WCT implementation" here...
I assumed you meant no changes from the WPF version's XAML

But I still think the WinUI design team will need to okay it and its variants - if only to confirm the spec to include in the figma toolkits

@kat-y If you are new to the project I apologize if I was sounding harsh. I do stand by my points above on how the project speed can be improved in some areas which is surely needs. Also, how we should use what has already been done in the past and heavily battle tested over the last 15 years. Of course none of this is directed personally to you or to anyone. It is a general 'bloat' problem I've seen with Microsoft for years where the teams need to be more streamlined and rebalanced in favor of more coding/less project management. As good as plans are nothing beats trial and error so speed of iteration wins in the end.

@ranjeshj @michael-hawker Why not use what is already done in the community toolkit? This isn't the first time the WinUI team seems to be taking a fresh approach. That needlessly duplicates work and causes fragmentation in the worst case. The WCT version was already based on the WPF ideas and made necessary 'modern' changes.

@ranjeshj @michael-hawker Why not use what is already done in the community toolkit? This isn't the first time the WinUI team seems to be taking a fresh approach. That needlessly duplicates work and causes fragmentation in the worst case. The WCT version was already based on the WPF ideas and made necessary 'modern' changes.

The Community Toolkit is in C# I believe, and WinUI requires C/C++ code.

Also the WinUI design team had no say AFAIK with the Toolkit version, and so the needs of the Windows and App design teams may have specific needs if they are to adopt the control, over their custom solutions.

The Community Toolkit is in C# I believe, and WinUI requires C/C++ code.

Translating code to/from C# & C++/WinRT is relatively trivial. Especially for the Expander where I already looked at the code https://github.com/windows-toolkit/WindowsCommunityToolkit/tree/master/Microsoft.Toolkit.Uwp.UI.Controls/Expander. The vast majority of complexity is in the XAML which is 1:1 usable in WinUI as long as no WCT extensions were used. I could port this code to C++ myself if it is needed.

Also the WinUI design team had no say AFAIK with the Toolkit version, and so the needs of the Windows and App design teams may have specific needs if they are to adopt the control, over their custom solutions.

For specific points, yes. However, for general control functionality I must disagree. The WCT would get us 95% complete already and 100% complete in functionality. Any design changes applied on top would be trivial.

@robloo Could you elaborate on which pieces of functionality are different ? The API proposed above matches very closely to WPF/WCT while trying to keep consistency with existing patterns in WinUI.

@ranjeshj We may not be on the same page. I wasn't suggesting that the proposed API was significantly different from WCT or WPF.

It was mentioned ExpandDirection may not be supported in the first version of this control. That seems like a problem for an Expander which has a long history with this functionality. Then it seemed like we have to justify why this feature is needed at all.

I suggested to use the WCT as base to quickly implement this with expand direction. There is no need to re-invent the wheel as only a port of C# -> C++ is needed (and code-behind is very small for this) while copy-pasting the XAML template. That would implement all functionality we would need and avoid concerns that there isn't enough time to add ExpandDirection. This approach would give us a fully functional control. Then any design/styling changes could be done on top based on @mdtauk or anyone else's suggestion. I don't understand (1) Why ExpandDirection is potentially on the chopping block for V1 (2) Why if time is a limitation we don't use existing code.

Yes my frustrations for WinUI 3 development in general are spilling into this a few places and I do apologize for that.

@robloo Its not about something being on the chopping block - but I believe the new people joining the team are there to offer a fresh look at these controls and APIs to see which are the greatest priorities - and potentially remove cruft when bringing new controls, or porting controls to WinUI.

When prioritising what features are essential to be included in a V1, and then in a V2, only the core and essential properties and behaviours will be there, and not legacy stuff that is not commonly used.

Microsoft seems to determine which features to add based on customer needs and wants - not just reaching parity with older frameworks.

So its not _justifying_, but just trying to understand what devs actually do with these control patterns in their UI.
The fact the Windows Shell alone has several versions of an expander control pattern, would be a clear enough reason why to include it. And the fact each implementation looks different, if not behaving different - is reason enough for the design team to consolidate the control design to meet the needs of the internal teams.

@mdtauk As always you make good points. However, I must disagree with this philosophy in one key way if it's truly the approach Microsoft is taking. For WinUI to be successful it must make sense for existing app developers. I'm trying to avoid another UWP scenario as we all know UWP never took off. The developers Microsoft needs to convince to come over to WinUI, just as UWP before, are WPF developers. One of the reasons WPF apps never made the jump to UWP is because UWP, especially when it was first released, was a very poor equivalent in several key areas of functionality. It's why when I saw rounded corners missing on the roadmap I started recalling the UWP nightmare (rounded corners fundamental to WPF were left out of UWP for the longest time). The number #1 priority should be for a smooth porting experience coming from BOTH WPF and UWP and honestly WPF should probably be a higher priority as there are far more apps there and Microsoft is clearly focusing on desktop cases with WinUI first. So again, we have to be very careful about, and actively avoid, reinventing the wheel.

And the fact each implementation looks different, if not behaving different - is reason enough for the design team to consolidate the control design to meet the needs of the internal teams.

I've always understood the design may need to be modified. Using lookless-control concepts this is a separate problem than ExpandDirection though. If we need to modernize the design more or make it more useful in some cases, great - it should be relatively trivial. At the end of the day it also may be fully re-templated for those that need fine control.

Interesting point about animations. We turn off all animations with the system setting, but I don't think we expose knobs to turn off animations other than by re-templating currently.

To be fair though, almost no controls use animations. TreeView and NavigationView essentially use a Expander but both don't use animations for expanding/collapsing. Most controls that use animations usually rely on them, e.g. ProgressBar or ProgressRing. Expander however does not rely on it, it would be more of a "nice to have". Another case in point is that some people didn't use the WCT Expander control because they disliked the animation. If we want to include as many people as possible, having an easy way to disable unwanted animations would make that easier.

I believe you could add a Style that overwrites the Transition collection with null in the case that you want to turn animations off, assuming there is a Transition collection to overwrite.

But would this be a common way of disabling/enabling that? Most of the time, when we provide multiple styles they differ more drastically than just one animation, e.g. AccentColorButtonStyle or RevealButtonStyle.

Including an ExpandTransition and CollapseTransition, that can use the direction set by the control's property - which could allow the dev to set the transition for each.

I really like this idea!

I like the idea, but I don't think there is a way today to create custom theme transitions which would limit the ability to customize. This would allow easily disable it though by removing it.

I am also concerned about that. with the ExpandTransition and CollapseTransition API without any custom theme transitions, this is close to just having a "ExpendTransitionEnabled" and "CollapseTransitionEnabled".

@robloo If you would like to chat about frustrations regarding WinUI 3 development, I welcome you to write me (my Twitter and work email are on my GitHub profile). I'm not fully aware of your current frustrations, but I'm generally a good person to start with for topics related to customer or community engagement/development as well as I've run a significant number of our focus groups over the last year that covered the considerations you've listed around tooling, feature parity, etc.

I'll note that our roadmap is extremely tight, so I can't promise I'll have the ability to make the changes you want to see, but it is always helpful for me to know what could be done to better support you as customer and/or contributor of WinUI, so the worst case outcome is that at least your needs are well considered by our team moving forward. For the best case, I suppose that will depend on what you're looking for. Let's chat? 馃槃

@mdtauk Thanks for your support in clarifying- you're always well in tune! I'll say that there is clearly a LOT on our plate and the teams is committed to being as lean and effective as possible in trying to deliver the most meaningful, impactful progress in all areas. To continue investing in new controls/features among all other areas of continued progress, it necessitates our team members like @kat-y developing _very_ sharp requirement specs as the worst thing for us would be throwing a portion of our limited resources at a knob or API that doesn't actually see broad use as there's not just the development cost upfront but also the continued maintenance cost after. I've only just parsed this thread lightly, but it is righteous for @kat-y, especially as a new team member, to want to be perfectly crisp in ensuring that there's a real scenario in a real app that needs the functionality requested (both for the reason stated and also to ensure we have Preview validation partners that are able to help ensure all the features developed perform as required in production environments that provide edge case coverage). Compliance with this aspiration may not always be publicly broadcast such as in cases where validating partners are private (and you're welcome to reach out to @kat-y directly if your needs are ones that aren't fit to be publicly posted about here at this time), but this has been a precedent in all of our WinUI 2+ control releases.

I hope this helped? It's my goal to turn this thread back over to @kat-y and the Expander topics at hand, but please reach out directly if there's more I can answer or if there's feedback you'd like to see considered. Thanks to both of you for all the work, passion, and energy you've put into this thread and into WinUI! 馃槃

@mdtauk As always you make good points. However, I must disagree with this philosophy in one key way if it's truly the approach Microsoft is taking..

I was not commenting on whether or not I agree with the approach, only that from my time on here and watching how repos are evaluated, it is how I believe the team is working on this.

(both for the reason stated and also to ensure we have Preview validation partners that are able to help ensure all the features developed perform as required in production environments that provide edge case coverage). Compliance with this aspiration may not always be publicly broadcast such as in cases where validating partners are private (and you're welcome to reach out to @kat-y directly if your needs are ones that aren't fit to be publicly posted about here at this time), but this has been a precedent in all of our WinUI 2+ control releases.

I believe using Microsoft's own apps, and Shell as examples are more likely to elicit recognition, as it shows where there was an internal need for something, which didn't exist, or was not fit for purpose, to the point they had to "roll their own" - but of course the big beasts like Netflix, Facebook, etc who build apps for Windows - will also ask for controls and other bits.

WinUI is not just about reaching parity with WPF, MFC, CommonControls, WinForms etc - (but the more commonly used of these legacy controls without a modern equivalent, should seriously be looked at)

The fact Breadcrumb Bars and Expanders are being proposed is a sign that this is starting to happen IMO. And every control or API addition should be evaluated and "justified" in an ideal environment, just as app designers should always be re-evaluating their UIs and UX to ensure they are fit for purpose. - In this case it may seem obvious, but we should still present examples where this pattern and these APIs are used - to strengthen the case for inclusion.

About the animations: How about using an ElementAnimator approach like the ItemsRepeater offers? The ElementAnimator API with its StartShowAnimation() and StartHideAnimation() looks promising ("show" to be used for expansion, "hide" used for collapsing). An ElementAnimator property could be offered on the control with a default animation implementation. If no animation is desired, the property could be set to null or if more fine-grained control is needed, only a Show or Hide animation could be supplied to the ElementAnimator.

I'm not too familiar with the ElementAnimator API and it seems it might not yet be usable in all scenarios as issue https://github.com/microsoft/microsoft-ui-xaml/issues/166 exists. However, if there is still a functionality gap, perhaps these work items (Expander control & ElementAnimator work to make it usable by the Expander control) could be synchronized and engineered together.

Hmm the ElementAnimator idea is really interesting. My concern here is that this might be too complicated or overengineered. After all, for the ExpanderControl, we would then need to provide a custom ElementAnimator while we otherwise could reuse existing theme animations. Also, ElementAnimator provides more methods than the expander control actually needs so it seems a bit like an awkward fit.

Am I right in thinking the ElementAnimator is for handling offsets for child or contained elements appearing on screen?

It may be overkill depending on what is within the panel that is shown as the expander, expands. But if there was a way to connect it somehow, so if the expanding panel containing elements - could drive child animations if the dev appends something onto the element.

So the Expander doesn't directly control the child element transitions, but could enable them if the dev wants to

Yes, if we could create re-usable aniamtions here, while still giving customers some satisfying level of customization options, then this would be worth exploring. For example, we have already seen asks to add animations to the TreeView control when an item expands/collapses (https://github.com/microsoft/microsoft-ui-xaml/issues/208). I imagine a case can be made here that one set of animations could be built to look great for both the Expander and the TreeView control. Which will automatically come with a level of consistency then among different controls. creating visual familiarity to the user which is also a compelling argument.

I think ideally, TreeView and hierachical NavigationView should just switch to Expander control when the control is ready. After all, currently both controls need to handle the exact same problem which would be solved by ExpanderControl. So a shared animation wouldn't make a big difference for TreeView.

The thing with ElementAnimator (how I understood it) is that we would have to write a new animation. However there are already built in animations we could leverage for Expander.

It may be overkill depending on what is within the panel that is shown as the expander, expands. But if there was a way to connect it somehow, so if the expanding panel containing elements - could drive child animations if the dev appends something onto the element.

I think one of the main points for ElementAnimator was to allow adding animations to panels and collections, e.g. ItemsRepeater. In the case of Expander, this isn't really the case though, expander is not a panel rendering a collection of items.

Off the top of my head, a resize for the parent panel with easing. Then a slide and fade for the containing object(s) would feel right.

If it were to become a generalised OS wide transition with the proper easing determined by the Fluent Design motion team - that would be good.

Tagging @stmoy since we are talking about animations.

Thank you @SavoySchuler for joining in and providing more context on our team's commitments - I hope this helps to explain why I'm specifically looking for examples of apps where the functionality of ExpandDirection is needed! To echo what Savoy said, please reach out to me directly (Twitter DMs if you need privacy) if your Expander needs are ones that can't be shared here.

@robloo Thank you for your apology, I completely understand your intentions and definitely want WinUI controls to be scoped and developed in a meaningful and efficient way. I am new to the team and really appreciate that the WinUI community is so friendly and enthusiastic in discussing the scope and implementation of Expander!

On that note, I'm excited to read through these more recent comments about animations!

After reading through the animations-related comments, it sounds like there are 3 possible routes, in order of increasing amount of work:

Not including a set animation - this has the benefit as @chingucoding pointed out of not deterring developers when their scenario doesn't work or look good with the set animation. The risk here is possible inconsistency, though there doesn't really seem to be a lot of 'room' for inconsistency in this route.

@mdtauk proposed Including an ExpandTransition and CollapseTransition,

that can use the direction set by the control's property - which could allow the dev to set the transition for each.

Sounds like a smaller scope than using ElementAnimator. Would this give developers complete flexibility in setting the transitions?

Off the top of my head, a resize for the parent panel with easing. Then a slide and fade for the containing object(s) would feel right.

I understand parts of this, but its hard for me to visualize without, well, a visual 馃槃. Does "resize for the parent panel" mean the header would change in size? Could you elaborate on what you mean by "a slide and fade for the containing object(s)"?

@Felix-Dev proposed using ElementAnimator

The ElementAnimator API with its StartShowAnimation() and StartHideAnimation() looks promising ("show" to be used for expansion, "hide" used for collapsing). An ElementAnimator property could be offered on the control with a default animation implementation. If no animation is desired, the property could be set to null or if more fine-grained control is needed, only a Show or Hide animation could be supplied to the ElementAnimator.

@chingucoding noted that

we would then need to provide a custom ElementAnimator while we otherwise could reuse existing theme animations. Also, ElementAnimator provides more methods than the expander control actually needs so it seems a bit like an awkward fit.

one of the main points for ElementAnimator was to allow adding animations to panels and collections, e.g. ItemsRepeater. In the case of Expander, this isn't really the case though, expander is not a panel rendering a collection of items.

TreeView and hierachical NavigationView should just switch to Expander control when the control is ready. After all, currently both controls need to handle the exact same problem which would be solved by ExpanderControl. So a shared animation wouldn't make a big difference for TreeView.

I'm not sure that TreeView and hierachical NavigationView have the exact same animation scenario as Expander, what about when Expander will push whatever content (not necessarily text/buttons) nearby and the scenarios when Expanders are 'accordion'-ed with each other and potentially have logic to close/open depending on each others' expansion.

Is ElementAnimator overkill for Expander animations given that it's intended for panel/collection animations?

@mdtauk proposed Including an ExpandTransition and CollapseTransition,

that can use the direction set by the control's property - which could allow the dev to set the transition for each.

Sounds like a smaller scope than using ElementAnimator. Would this give developers complete flexibility in setting the transitions?

Off the top of my head, a resize for the parent panel with easing. Then a slide and fade for the containing object(s) would feel right.

I understand parts of this, but its hard for me to visualize without, well, a visual 馃槃. Does "resize for the parent panel" mean the header would change in size? Could you elaborate on what you mean by "a slide and fade for the containing object(s)"?

expander_motion

Sorry for the delay, I had to make this little mock-up animation.
Ignore the actual animation timings, they are just for illustration. The Pink outline is the Expander Header - and the Green Border is for the Expander Pane/Content etc

I'm not sure that TreeView and hierachical NavigationView have the exact same animation scenario as Expander, what about when Expander will push whatever content (not necessarily text/buttons) nearby and the scenarios when Expanders are 'accordion'-ed with each other and potentially have logic to close/open depending on each others' expansion.

The question is, should Expander enforce animations though? TreeView and Hierarchical NavigationView definitely would benefit from having a built in expander control that takes care of the expanding/collapsing and would allow us to be able to have a more unified experience in that area. For example, TreeView does not animate anything while hierarchical NavigationView animates the rotating of the chevron.

Is ElementAnimator overkill for Expander animations given that it's intended for panel/collection animations?

It might be, one of the controls that actively support ElementAnimator (at least in preview) is ItemsRepeater which deals with large panels rendering dozens of items. Expander on the other hand does not have such a complex scenario but rather one single item to show/hide.


A different thing I noticed is that there wouldn't be a way to customize where the chevron would be placed (left/right or top/bottom). Maybe this would be useful to have as a customization point? NavigationView places the chevron on the right while TreeView places it on the left. Same goes for existing expanders in the system, some areas of the settings app place it on the left while Notifications for example, place them on the right.

A different thing I noticed is that there wouldn't be a way to customize where the chevron would be placed (left/right or top/bottom). Maybe this would be useful to have as a customization point? NavigationView places the chevron on the right while TreeView places it on the left. Same goes for existing expanders in the system, some areas of the settings app place it on the left while Notifications for example, place them on the right.

We could introduce something like an ExpandGlyphPlacementMode with values like TopLeft, TopRight, BottomCentered (and possibly more (Left, Right, ...)) and an additional ExpandGlyphPlacementOffset property developers could use to modify the base position (set by placement mode) if required.

In addition to that, as @mdtauk already noticed, APIs to customize the expand/collapse glyphs (some controls use >, others use v for their expand glyph) and to control the visibility of the glyph.

We could introduce something like an ExpandGlyphPlacementMode with values like TopLeft, TopRight, BottomCentered (and possibly more (Left, Right, ...)) and an additional ExpandGlyphPlacementOffset property developers could use to modify the base position (set by placement mode) if required.

I am not sure if TopLeft, TopRight ... is the right choice here. Maybe something like "Start" and "End" might be better suited here?
In horizontal layouts, Start would be on the left (right in RTL languages), in vertical opening mode, this would be top. "End" could be defined accordingly then. The issue I see with TopLeft ... is that it introduces a lot of complexity (see TeachingTip) for little benefit. TopLeft and TopRight would be the same if the ExpanderControl opens to the right. I think having something like bottom centered is going to look a bit awkward in a lot of spaces and take up a lot of space.

In addition to that, as @ mdtauk (splitting up mention to not spam his inbox) already noticed, APIs to customize the expand/collapse glyphs (some controls use >, others use v for their expand glyph) and to control the visibility of the glyph.

The question is, how to achieve this. If we want to animate the icon similiarly to what hierarchical NavigationView does, we won't be able to allow an API for swapping out the expanded and collapsed glyph which could be used to switch to v or > for collapsed. Maybe we could have an API indicating the collapsed glyph direction?

The ideas for animations seem pretty good. It needs to be possible to turn them on/off just like List View, et al. The header and glyph also need to switch sides for RTL languages automatically. However, all the glyph customization seems to be overengineering the problem. It is impossible to create a style that will work for all cases identified that have custom implementations. Instead, just like CheckBox and other controls, the default design should be the best we can do but the default style should be simple enough to re-template. I dont know why everyone is so adverse to re-templating controls it very much is the solution and is actually a great strength of look less controls. Adding more properties is also increasing that maintenance burden I hear so much about.

Edit: defining resources for a few things to improve lightweight styling might be a reasonable option as well.

I am not sure if TopLeft, TopRight ... is the right choice here. Maybe something like "Start" and "End" might be better suited here?
In horizontal layouts, Start would be on the left (right in RTL languages), in vertical opening mode, this would be top. "End" could be defined accordingly then. The issue I see with TopLeft ... is that it introduces a lot of complexity (see TeachingTip) for little benefit.

@chingucoding The NavigationView uses a vertical opening mode (since a NavigationViewItem expands vertically), right? How would I then be able to set the glyph either on the left or the right side of the header? I'm reading your comment as "start" would be top, "end" probably bottom of the header then. But I'm not seeing a way to specify if the glyph can be placed in the top left corner or the top-right corner. I shouldn't have to use an API like ExpandGlyphPlacementOffset for something we are seeing that commonly.

I think having something like bottom centered is going to look a bit awkward in a lot of spaces and take up a lot of space.

I am sure I have seen examples of that on the web, in apps, etc...which is why I came up with that idea. Though it would best if examples could be posted here to see if that is something worth supporting directly or whether we would leave that up to re-templating.

However, all the glyph customization seems to be overengineering the problem. It is impossible to create a style that will work for all cases identified that have custom implementations. Instead, just like CheckBox and other controls, the default design should be the best we can do but the default style should be simple enough to re-template. I dont know why everyone is so adverse to re-templating controls it very much is the solution and is actually a great strength of look less controls.

@robloo I'm not adverse to re-templating but looking at the examples posted so far, some developers use ">" for the expansion glyoh and others use "v" for the expansion glyph when expanding vertically. Same as for the position of the glyph. The Expander control should make it very easy for developers to set the glyph according to their wishes. Re-templating always comes with trade-offs, mainly that you won't automatically benefit from future changes being made to the control template in WinUI. Instead, that burden will be now on the developers to maintain their customized template.

We should identify common customization scenarios and strive to make them as accessible as possible by the Expander control.

Take, for example, this case of customized glyphs (found on the Fluent UI website):
fluent-ui-website-expand

Glyph symbol customization will necessarily mean any in-built glyph animation has to be considered carefully. Also interestingly to know: What would be more desired by customers - the ability to easily customize the glyphs according to their liking or having an in-built animation for the glyph (like seen in the NavigationView). I personally think the former would be more important to have but I don't have any hard data to back that up.

Another Expander control is the Telerik Expander control which exposes some of the customization APIs we have been discussing here (like the ability to change the position of the glyoh or the glyph symbol) which we could also use for some inspiration.

ExpandedGlyph
CollapsedGlyph
Which the developer could override as they see fit

GlyphPlacement.Start .End .Above .Below
Maybe?

Maybe also use content alignment to handle the header filling the width, or have the Glyph and text bunched up together

For the Notification Centre there is a clear all on the same line as the expander, so how would this be handled? Some kind of way to separate the expanding panel from the expanding header?

@chingucoding The NavigationView uses a vertical opening mode (since a NavigationViewItem expands vertically), right? How would I then be able to set the glyph either on the left or the right side of the header? I'm reading your comment as "start" would be top, "end" probably bottom of the header then. But I'm not seeing a way to specify if the glyph can be placed in the top left corner or the top-right corner. I shouldn't have to use an API like ExpandGlyphPlacementOffset for something we are seeing that commonly.

That was poorly worded on my end With "horizontal opening mode", I meant that the horizontal dimension is fixed, so the content is presented in a horizontal fashion. Same for vertical mode. Also what is the top left and bottom left corner? I would assume the icon to be centered, most of the time the header shouldn't/doesn't even take up to much space in the expanding region and top left and bottom left would end up being almost the same.

So to clarify, if the expander expands in vertical direction, start is left (right in RTL) and end is right (left in RTL); in horizontal expansion, start is top and end is bottom. Similar to CSS flex-start and flex-end.

Visual Studio uses a centered icon, however the expand button region stretches the whole control:

Closed:
image

Expanded:

image

GlyphPlacement.Start .End .Above .Below
Maybe?

That sounds like a very cool idea! How would above and below look like? Similar to what Visual Studio does?

ExpandedGlyph
CollapsedGlyph
Which the developer could override as they see fit

This would be a way to do this, however this wouldn't allow us to animate the icon (e.g. rotating). However I think it makes more sense to prioritize the possibility to switch out the icon entirely than to have an animation here.

Maybe also use content alignment to handle the header filling the width, or have the Glyph and text bunched up together

100%

For the Notification Centre there is a clear all on the same line as the expander, so how would this be handled? Some kind of way to separate the expanding panel from the expanding header?

I am concerned that this specific scenario might be too complex to achieve simply with the expander control. The placement of the buttons are quite unique, but more importantly, the header and the expand icon are not on the same line which would be quite hard to do with a standard expander control that puts header and icon next to each other. Here is an example for reference:

image

I'm not adverse to re-templating but looking at the examples posted so far, some developers use ">" for the expansion glyoh and others use "v" for the expansion glyph when expanding vertically. Same as for the position of the glyph. The Expander control should make it very easy for developers to set the glyph according to their wishes.

@Felix-Dev This is one of those things that should be standardized in the fluent design system. It's important for users to have a consistent look and feel. The only time this should change is if an app must do it to meet their own design language or there is a new use case we didn't think of. In that case -- re-template.

Edit: I missed your Telerik example on first read. Still think we are increasing complexity too much and allowing too many design options that will: (1) not be as easily recognized by users (2) will expose a lot of complexity that hasn't historically been needed. Of course there is a fine line here. We want to expose enough functionality that users don't need to re-template, but we also don't want to expose so much functionality that the design language becomes muddied.

WPF, or any other expander controls I can think of, never exposed a property to control this. It really is very much part of the view and should persist only in XAML. The view model (i.e. DPs of the control in this case) should not know anything about such a styling choice in a clean lookless control.

WPF, or any other expander controls I can think of, never exposed a property to control this. It really is very much part of the view and should persist only in XAML. The view model (i.e. DPs of the control in this case) should not know anything about such a styling choice in a clean lookless control.

@robloo One possibility to expose glyph customization would be through lightweight-styling. These resources, just as DPs, should be considered part of the public API surface of a control, but they are much closer to the control template (the look of the control). So we could expose resources like a ExpanderExpandGlyph and a ExpanderCollapseGlyph (the NavigationView for example has a NavigationViewItemExpandedGlyph resource).

Exposing glyph symbol customization that way could also be read as a recommendation to supply font elements present in the MDL2 font, thus using Fluent Design approved icons. Looking at the MDL2 font, it seems to feature all of the commonly used expand/collapse glyph icons I have seen in examples around the web (the different chevrons, +/-, +/- in circles,...). While developers could probably still override the FontFamily (supplied by the SymbolThemeFontFamily resource), we would only directly expose the ExpanderExpandGlyph,... resources as public resources for the control, thus developers will potentially first look at the MDL2 font family if they want to customize the icons (since that would be the default font family used by the Expander for the glyphs).

For those interested, there is also at least one other yet unresolved issue about how far we as WinUI want to go to provide easy customization glyph options when only a fixed set of icons will make sense in the given context (NumberBox spin buttons glyph customization): https://github.com/microsoft/microsoft-ui-xaml/issues/2789 I know at least some of you are already aware of that issue, but as I'm seeing some parallels in the discussion over there as over here regarding how to expose (glyph) customization option I felt it worth referencing here. Perhaps the solution found here can also be applied in the NumberBox case for consistency in WinUI.

@Felix-Dev Your recommendation for lightweight styling makes the most sense to me. It's what I meant by "Edit: defining resources for a few things to improve lightweight styling might be a reasonable option as well." a few comments above.

The question is how likely developers are not going to provide a glyph but rather have some form of other icon, e.g. a BitmapIcon or some form of custom FontIcon. If non glyph icons are not really a customization point many developers would use, I think a lightweight styling resource for the glyph (and maybe one for the symbol font) to use is the best thing here, as proposed by @robloo and @Felix-Dev .

Re-templating is always an option, if a glyph or custom font is not enough.

  • Font Glyphs either with Segoe MDL2 or FluentIcons are the most likely and should probably be the default;
  • No glyph at all is also common;

  • Then there are paths, SVGs that are less likely but very possible;

  • And then PNGs or full bitmaps as a not likely but may be possible option for devs.

Whatever approach is used, should probably focus on the first two scenarios, but always allow re-templating for the third.


Then there is the possibility to have a ContentPresenter for the glyph, and allow anything to be put on it. But not sure how that works with the VisualStates for moving from Collapsed to Expanded.


As for animating the icon - perhaps the Lottie control could be used here?


Another thought, just as you have the RadioButton and RadioButtons as a group of them...

Should a group of Expanders make an Accordion Control? Which would allow for a behaviour where only a single expander can be expanded at a time?
image
https://explore.fast.design/components/fast-accordion

Re-templating is always an option, if a glyph or custom font is not enough.

Font Glyphs either with Segoe MDL2 or FluentIcons are the most likely and should probably be the default;

No glyph at all is also common;

Then there are paths, SVGs that are less likely but very possible;

And then PNGs or full bitmaps as a not likely but may be possible option for devs.

Whatever approach is used, should probably focus on the first two scenarios, but always allow re-templating for the third.

Retemplating will always be an option, however of course that is something that can break over time if there are (major) changes to the control. So having a lightweight resource is probably the best here as switching out glyphs (and icon font) are the most common scenarios.

Then there is the possibility to have a ContentPresenter for the glyph, and allow anything to be put on it. But not sure how that works with the VisualStates for moving from Collapsed to Expanded.

Using a ContentPresenter doesn't make a difference regarding collapsing/expanding, it would be just an element like the others.

As for animating the icon - perhaps the Lottie control could be used here?

The question is what kind of animations you want to have. Simple rotation can (and is) already done without lottie.

Another thought, just as you have the RadioButton and RadioButtons as a group of them...

Should a group of Expanders make an Accordion Control? Which would allow for a behaviour where only a single expander can be expanded at a time?

Maybe that could be separate control? While there are scenarios where they could be exclusive to each other, I think in a lot of cases, it doesn't really matter if multiple are open.

Then there is the possibility to have a ContentPresenter for the glyph, and allow anything to be put on it. But not sure how that works with the VisualStates for moving from Collapsed to Expanded.

Using a ContentPresenter doesn't make a difference regarding collapsing/expanding, it would be just an element like the others.

But would it be a ContentPresenter which is used by both states, or one per state that gets swapped out/toggled?

As for animating the icon - perhaps the Lottie control could be used here?

The question is what kind of animations you want to have. Simple rotation can (and is) already done without lottie.

Rotations make sense when the glyph is a directional arrow/chevron - but what if its a light bulb turning on and off for some kind of tip or hint scenario? There is a proposal for a generalised animated icon control using Lottie #2802 - would this situation call for this, even if its default/most common use may be a simple icon rotation?

Another thought, just as you have the RadioButton and RadioButtons as a group of them...
Should a group of Expanders make an Accordion Control? Which would allow for a behaviour where only a single expander can be expanded at a time?

Maybe that could be separate control? While there are scenarios where they could be exclusive to each other, I think in a lot of cases, it doesn't really matter if multiple are open.

I mention it only as Fast Design includes an accordion control, and it is essentially the same as a bunch of expanders - only that there is a Multi and Single behaviour API which changes how they work together. With an Expander control made, an Accordion would be a logical next step and should be relatively easy to achieve with an orientation property to override the individual directions.

Then there is the possibility to have a ContentPresenter for the glyph, and allow anything to be put on it. But not sure how that works with the VisualStates for moving from Collapsed to Expanded.

Using a ContentPresenter doesn't make a difference regarding collapsing/expanding, it would be just an element like the others.

But would it be a ContentPresenter which is used by both states, or one per state that gets swapped out/toggled?

Both options make sense. I think switching the content of the ContentPresenter is better than swapping out the ContentPresenter or having two and hiding/showing one.

As for animating the icon - perhaps the Lottie control could be used here?

The question is what kind of animations you want to have. Simple rotation can (and is) already done without lottie.

Rotations make sense when the glyph is a directional arrow/chevron - but what if its a light bulb turning on and off for some kind of tip or hint scenario? There is a proposal for a generalised animated icon control using Lottie #2802 - would this situation call for this, even if its default/most common use may be a simple icon rotation?

A rotation animation would be one way to animate and would be easy to achieve. Having an icon that animates into a different one would be quite different. That would also probably make the API more complicated (how do you support such behavior? 2 animations and 2 icons? or one animation that you stop?)

Another thought, just as you have the RadioButton and RadioButtons as a group of them...
Should a group of Expanders make an Accordion Control? Which would allow for a behaviour where only a single expander can be expanded at a time?

Maybe that could be separate control? While there are scenarios where they could be exclusive to each other, I think in a lot of cases, it doesn't really matter if multiple are open.

I mention it only as Fast Design includes an accordion control, and it is essentially the same as a bunch of expanders - only that there is a Multi and Single behaviour API which changes how they work together. With an Expander control made, an Accordion would be a logical next step and should be relatively easy to achieve with an orientation property to override the individual directions.

Right, I see. Yes an accordion control is definitely a good idea after expander control and would probably be every easy to implement!

Rotations make sense when the glyph is a directional arrow/chevron - but what if its a light bulb turning on and off for some kind of tip or hint scenario? There is a proposal for a generalised animated icon control using Lottie #2802 - would this situation call for this, even if its default/most common use may be a simple icon rotation?

A rotation animation would be one way to animate and would be easy to achieve. Having an icon that animates into a different one would be quite different. That would also probably make the API more complicated (how do you support such behavior? 2 animations and 2 icons? or one animation that you stop?)

This is a big question, and to be honest, is something for the Animated Icon proposal.

Animating the glyph/icon is fine if it will always be an arrow. But it kind of locks that in, unless you have an easy way to remove or change the animation itself.

Making a rotating Lottie animation keeps the default animation, means a little more work to implement, but is more flexible in allowing changing the icon and animations if needed.

The easiest option is to just have no animation for the glyph. But the more you add in, making it easy to override or change becomes more important.

Looking through the web I see quite a lof of static icons used for the expand/collapse glyphs in typical Expander UI examples. However, on Windows, we also have potential customers of this control who seem to prefer animations (see for example the NavigationView and toast notifications in the shell). Motion is one of the cornerstones of Fluent Design so it probably makes sense here to keep options open for those customers who want an animated glyph without being required to re-template the control.

Ideally, if different teams at MS would like to use an Expander with an animated glyph (i.e. animated arrow glyph) the control would provide an in-built option so we end up having a consistent experience by default. If each team were to be responsible themself for the animation, we might end up seeing different animation duration, different animation directions (i.e. clockwise or counter-clockwise),...If I recall correctly, the animation of the glyph for notifications in the action center is different to the animation of the glyph in the NavigationView. That should be avoided, if possible.

Animations are a delighter, and help make the UI feel smooth. Hard coding in a rotation Storyboard, is the simple way to add an animation, but if that animation is difficult to remove, or change - perhaps using the AnimatedIcon control would be a good way to make a flexible way to enable customisation.

I am not saying one way is better than the other - just bringing it to attention here, as it is animating an icon, and that is the Raison Detra for the new control.

And if it has been acknowledged that the glyphs should be customisable - the rotation animation may not always be appropriate.

What to animate and what not to animate is a very difficult question. As Martin already mentioned, a rotation animation does not always make sense. And animated icons still have a lot of open questions.

I think it might be better to scratch glyph/icon animations for v1 then, especially since it is not very common. One thing to reconsider then is if we remove the existing animation on the hierarchical NavigationView to have a uniform experience. Currently there already is inconsistency between TreeView and h-NavigationView on to animate/not animate the switching of the icon.

Exactly. I wasn't meaning to discourage any exploration here with my last paragraph but just writing once again that one of the challenges we are facing here is about providing enough customization options outside of "the ultimate one" - re-templating - to satisfy common customer wants, yet still making sure that the control will help bring more consistency to Windows, instead of potentially less.

As we have already seen there might not be a perfect solution here since wanting to provide both icon customizations and animation support (perhaps in addition to built-in animations for consistency) can easily collide with each other.

It could be helpful to get potential customers like the Windows Shell on board here to see how they view animations. 10X will supposedly put some focus on animations and the Windows Shell and in-box Windows apps could be "customers" here. If an animated glyph is considered an important piece in the overall UX the Windows team is striving for with 10X, that could require not "punting" on this challenge for now, but instead feature animation support in V1.

I would like to see a consistent approach to animating icons, which right now appears to be the Animated Icon proposal.

I would not remove any animation from the NavigationView, as it is an entirely self contained new paradigm for WinUI - and it seems as though the intention is to add animations to all these similar controls - so maybe once it is ready, the control could be added to the NavigationView

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

@mdtauk thank you for making the mock-up animation! I understand what you meant for the expanding and collapsing animations.

I believe that accordion behavior will be achieved through list-level logic (rather than a new Accordion control) with IsExpanded for developers to customize this to different scenarios (Ex: where some Expanders close each other and others can simultaneously be expanded).

@Felix-Dev - I've added the Telerik Expander to the proposal, thanks for sharing it!

It sounds there's a desire for customizability in the following directions:

Glyph appearance: lightweight styling seems to be the preferred route to switch out glyphs and icon font, through having ExpanderExpandGlyph and ExpanderCollapseGlyph. Is this level of customization needed in v1 Expander?

@Felix-Dev While developers could probably still override the FontFamily (supplied by the SymbolThemeFontFamily resource), we would only directly expose the ExpanderExpandGlyph ... thus developers will potentially first look at the MDL2 font family if they want to customize the icons (since that would be the default font family used by the Expander for the glyphs).

Glyph animation: including change to a different glyph upon expansion - which is partially solved with AnimatedIcon #2802. Sounds like this level of customization is not necessary for v1 Expander.
@chingucoding stated and I tend to agree:

I think it might be better to scratch glyph/icon animations for v1 then, especially since it is not very common.

Glyph position: Is this level of customization needed in v1 Expander? This is further complicated if v1 includes ExpandDirection and the option to change glyph position. @Felix-Dev described

Something like an ExpandGlyphPlacementMode with values like TopLeft, TopRight, BottomCentered (and possibly more (Left, Right, ...)) and an additional ExpandGlyphPlacementOffset property developers could use to modify the base position (set by placement mode) if required.

Hope I've correctly understood the great discussion from this weekend - let me know if I'm mistaken somewhere! Thank you all so much for your insightful thoughts on this. 馃槃

Glyph Appearance
Glyph Position

I think these are the easiest and most important customisations to include in V1.

I would also add a way to hide the Glyph

Glyph Animation
State Transitions

These could be given a lower priority if Prioritisation is needed and the core behaviour and functionality is taking too long.

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?

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

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.

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

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?

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?

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

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 馃槃

Was this page helpful?
0 / 5 - 0 ratings