-
Notifications
You must be signed in to change notification settings - Fork 808
Description
The WinUI Team has opened a spec and PR for this feature.
Proposal: Tabs Control
Summary
The Tab control is a way to display a set of tabs and their respective content. Tab controls are useful for displaying several pages (or documents) of content while giving a user the capability to rearrange, open, or close new tabs.
Rationale
As a UI paradigm, Tabs has been around for a long time, and can be found in everything from dialogs to browsers. The focus for this proposal is "document-style" tabs, which enables a user to rearrange, open, and close new tabs.
Note that "static-style" tabs also exist as a paradigm. "Static-style" tabs are tabs that do not support user interaction beyond switching tabs. UWP already has a solution for static-style tabs in the form of Pivot and NavigationView.
A lack of a proper Tab control has been a continual painpoint in UWP, particularly for developers attempting to migrate from WPF.
The XAML platform provides a number of ways to achieve "static-style" tabs in Pivot and top NavigationView. However, these solutions do not well support "document-style" tabs which support user reorder, opening, and closing tabs. The platform does demonstrate how to create "document-style" tabs in the Van Arsdel sample using top NavigationView:

Although these workarounds have unblocked apps trying to create "document-style" tabs, they have a number of limitations, including:
- Significant effort up to (and including) retemplating to build simple tabs
- No built-in support for closing tabs
- No built-in support for drag/drop into new windows
- No built-in support for moving a tab from a window and combining it with another window
- Limited keyboard and accessibility support
Fortunately, the Windows Community Toolkit has created a TabView control that helps address some of the aforementioned pain points.
However, the Windows Community Toolkit is a managed/C# project, meaning that customers that don't want to load the CLR or are particularly performance-focused cannot leverage the Windows Community Toolkit implementation.
The goal for this feature proposal is not to "reinvent the wheel" - instead, we hope to take the learnings from the WCT implementation and discussion and build a native control directly into WinUI.
Functional Requirements
| # | Feature | Priority |
|---|---|---|
| 1. | User can switch tabs using common inputs (like ctrl+tab) | Must |
| 2. | Control has a mode to close tabs | Must |
| 3. | User can open new tabs | Must |
| 4. | Control supports tab "tear off" | Must |
| 5. | Control supports tab "recombination" (both into the same Tab group or between Tab groups) | Must |
| 6. | Control supports tab reorder | Must |
| 7. | Control supports data binding to a collection of tabs | Must |
| 8. | Control supports a custom header/footer | Must |
| 9. | When not all tabs fit, control provides affordance to access all tabs | Must |
| 10. | Tab items can have a label and icon | Should |
| 11. | Tab height, width, and template can be customized | Should |
| 12. | The app may decide how size the tabs relative to each other (ie. equally sized, sized to content, etc.) | Should |
| 13. | The control supports Tab Placement with tabs on the Left, Right, or Bottom. | Could |
| 14. | App can specify specific "unclosable" tabs | Could |
Important Notes
To replicate the behavior of Microsoft Edge:
<TabControl TabWidthBehavior="Equal"
CanCloseTabs="True"
CloseButtonOverlay="OnHover"
CanDragItems="True"
CanReorderItems="True"
TabDraggedOutside="OpenTabInNewWindow">
<TabControl.TabFooter>
<Button Content="+" Click="NewTab_Click" />
</TabControl.TabFooter>
...
</TabControl>The TabControl also supports databinding:
<TabControl ItemsSource="{x:Bind TabItemCollection}" />TabControl properties and events
| Property | Type | Description |
|---|---|---|
| CanCloseTabs | bool | Default value for the item if it doesn't specify a IsClosable value. |
| CloseButtonOverlay | enum | Describes the behavior of the close button. Values are {Auto, OnHover, Persistent} |
| ItemHeaderTemplate | DataTemplate | Default template for the item if no template specified. |
| SelectedTabWidth | double | The size of the selected tab header. |
| TabHeader | object | Content to the left of the tab strip. |
| TabHeaderTemplate | DataTemplate | Template for the Header. |
| TabFooter | object | Content to the far right of the tab strip. |
| TabFooterTemplate | DataTemplate | Template for the Footer. |
| TabActionContent | object | Content immediately to the right of the tabs |
| TabActionContentTemplate | DataTemplate | Template for the ActionContent. |
| TabWidthBehavior | enum | Specifies how the tabs should be sized. Values are {Actual, Equal, Compact} |
| Event | Description |
|---|---|
| TabClosing | Fires when a tab is about to be closed. Can be cancelled to prevent closure. |
| TabDraggedOutside | Fires when a Tab is dragged outside of the Tab bar. |
TabItem properties and events
| Property | Type | Description |
|---|---|---|
| Content | object | The main content that appears in the tab. |
| Header | object | The content that appears inside the tab itself. |
| HeaderTemplate | DataTemplate | Template for the header object. |
| Icon | IconElement | Icon for the tab. |
| IsClosable | bool | Determines if the tab shows a close button. |
| Event | Description |
|---|---|
| TabClosing | Fires when a tab's close button is clicked. |
Open Questions
1. Should Tab Tearoff be something that the control handles or that the app handles?
The app will handle it. We will have good samples showing how.
2. Should there be a built-in "Add new tab" button? (I suspect probably not, because the control doesn't own the collection of Tabs.)
The app will own the "Add tab" button. In the case of Terminal, for example, they will add a button with a dropdown. Adding an "Add" button doesn't add much value.
3. Should TabItem.Icon be IconElement or IconElementSource?
IconElement. IconElementSource is useful when the same icon could appear in multiple places in the tree, which isn't the case here.
-
How can an app customize that the Selected tab looks like (ie. in Edge)?
-
The API currently takes a lot of inspiration from the Toolkit. Are there any chances to iterate/improve?
Release Checklists
Prerelease readiness
- Dev: quality review + code review done
- Dev: test coverage added
- Dev: initial accessibility review done
- Dev: telemetry implemented
- PM: spec up to date
- PM: feature ready for feedback
- PM: docs.microsoft.com updates ready
Stable release readiness
- Dev: feature previously shipped in a prerelease NuGet package
- Dev: Azure CI tests passing
- Dev: accessibility review done
- Dev: API review done
- Dev: IDL attribute switched from preview to public
- Dev: Add test coverage to the NugetReleaseTest test
- PM: spec done
- PM: glob/loc, privacy, security, license compliance ready
- PM: customer validation done
- PM: docs.microsoft.com updated
- PM: Xaml Controls Gallery updated





