Skip to content

Conversation

@dipeshmsft
Copy link
Member

This is an API Spec PR for the proposed SplitMenuFlyoutItem control.

PR Type

Please check the type of change your PR introduces:

  • Bugfix
  • Feature
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

Description

The SplitMenuFlyoutItem control is proposed to be a new addition to the WinUI library, designed to provide a split button experience within a menu flyout. This control derives from MenuFlyoutItem and introduces a dual-button interface consisting of a primary button and a flyout button.

Motivation and Context

This functionality will allow developers to expose a default primary action while also offering additional options through an attached dropdown — ideal for condensing complex functionality into a smaller footprint and saving overall menu length.

How Has This Been Tested?

  • I have performed a self-review of my own code
  • I have added tests to cover my changes

Screenshots (if appropriate):

Attached in the document.

@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Oct 30, 2025
@eduardobragaxz
Copy link

AppBarSplitButton would be nice too 👀

@michael-hawker michael-hawker moved this to API Review - Gathering Feedback in API Specs Review Oct 30, 2025
@michael-hawker
Copy link
Collaborator

I've added this to the public api review process board: https://aka.ms/winappsdk/api-specs-review

This PR will be open for feedback for a month from its opening: October 30th – November 30th

FYI @dipeshmsft

@michael-hawker michael-hawker added SpecInReview and removed needs-triage Issue needs to be triaged by the area owners labels Oct 30, 2025
@dipeshmsft dipeshmsft changed the title Added specs for SplitMenuFlyoutItem control [API Spec] SplitMenuFlyoutItem control Nov 3, 2025
@whiskhub
Copy link
Contributor

whiskhub commented Nov 3, 2025

Please consider referencing all resources in XAML with ThemeResource, even values like thickness, height etc. This allows users to overwrite resources for lightweight styling. See #6945

For example, MenuFlyoutItemThemePaddingNarrow, SplitMenuFlyoutItemSeparatorHeight, SplitMenuFlyoutItemChevronButtonWidth, MenuFlyoutItemChevronMargin seem to be referenced as StaticResource right now. 3e4702c...b05521d#diff-2ded3dd0ba19e54f4d02039304a6094d2945899e86e8e039e91af5d738da83c9R602

@riverar
Copy link
Contributor

riverar commented Nov 6, 2025

I have UX concerns about the current proposal/implementation where the context menu item reads "Compress to ZIP" but opens a sub-menu with alternative formats (7z, tar.gz, etc.).

The chevron (>) establishes a visual contract that the sub-menu contains sub-options or refinements of the parent item. However, this control actually presents alternative actions that contradict the parent label. When users see "Compress to ZIP >", they reasonably expect ZIP-related options (compression levels, encryption, split archives), not completely different formats.

Example: Imagine a context menu item labeled "Email to John >" that opens a sub-menu with "Slack John", "Call John", "Text John". While all communicate with John, the parent item explicitly promised email.

Are there existing Windows patterns or any other examples to support this "specific action > alternative actions" model that I'm not aware of?

including the `SplitMenuFlyoutItem`.
- When focus is coming from a menu item above the current menu item i.e. focus is coming as a result of Down Arrow Key,
the focus will move to primary button. Similarly, when the focus is coming from below,
i.e. focus is coming to this control as a result of Up Arrow Key, focus first moves to secondary button.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's confusing. I think if a user is keyboarding through a context menu with items that can open sub-menus, they would expect up/down to select only primary items. If they are interested in other options, they will explore those by moving to the item and pressing right-arrow.

(LTR layout assumed)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We chose the above behavior to accommodate users who would be using a screen reader. If we use Up/Down arrow keys to navigate to primary button and then to next item, it hampers the discoverability of the secondary button.

This same pattern is followed in Teams desktop application.
Here is a sample of the Split Menu Item that already exists in Fluent UI React 9: https://storybooks.fluentui.dev/react/?path=/docs/components-menu-menu--docs#split-menu-item

Copy link
Contributor

@riverar riverar Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting!

image

Microsoft PowerPoint's SplitButton is announced by screen readers (nvda, msft) as 🗣️ Grid and Guides..., SplitButton, collapsed, 1 of 2. The collapsed state is communicated the user so they are aware it can be expanded.

image

Fluent (web)'s MenuItem/MenuSplitGroup (ignoring their menu item count accessibility bugs) is announced by screen readers as 🗣️ Open, menu item, 1 of 2 and 🗣️ Open on platform, menu item, collapsed, 2 of 2.

That's pretty good too, however I'm not a huge fan of the screen reader user being told there are two menu items (seemingly with text) when there are in fact not. This could lead to confusion when, say, asking other users to click on the Open on platform menu item that doesn't actually exist. (Perhaps that could be mitigated by simply announcing it as the Open chevron? 🤔)

I think with that mitigation in place, your proposed workflow is acceptable.

@riverar
Copy link
Contributor

riverar commented Nov 6, 2025

If this control is already in experimental3, which is already in the pipeline for release, what impact will this PR really have?

@dipeshmsft
Copy link
Member Author

dipeshmsft commented Nov 7, 2025

@riverar

I have UX concerns about the current proposal/implementation where the context menu item reads "Compress to ZIP" but opens a sub-menu with alternative formats (7z, tar.gz, etc.).
The chevron (>) establishes a visual contract that the sub-menu contains sub-options or refinements of the parent item. However, this control actually presents alternative actions that contradict the parent label. When users see "Compress to ZIP >", they reasonably expect ZIP-related options (compression levels, encryption, split archives), not completely different formats.

"Compress to ZIP" scenario may not be the best scenario for SplitMenuFlyoutItem and maybe more suited for MenuFlyoutSubItem.

I would like to draw your attention to the Paste example, where there are different ways of performing the paste - "Paste as Text", "Paste with Merge Formatting", "Paste with Source Formatting", etc. This is one of the true examples of what we are trying to achieve using this control. If there are multiple ways of performing one operation and the app developer wants to set one as the default mode operation, those scenarios are the ones that we are trying to support using this control.

In the example of having a menu item "Email to John" and then inside that command having sub-menu items like "Slack to John", "Call John", this is geared towards the default mode of action for a user. Say it is by mail, so we show that in the primary part, and other parts of making contact are secondary, so they are put in the sub menu item.

However, I think the control is general enough to support both the cases : having alternate actions grouped together, and handling different variations of the same action.

In the light of the confusion this is creating I will go ahead and modify the usage examples in the API spec.

@dipeshmsft
Copy link
Member Author

dipeshmsft commented Nov 7, 2025

If this control is already in experimental3, which is already in the pipeline for release, what impact will this PR really have?

@riverar, we have done 2 passes on internal review for this control, however since this is still in experimental, we are open to suggestions.


Here is one example of a customized submenu (this is a reference from the SplitButton control).

![Customizable SubMenu Scarnario](./customizable-submenu-sample.png)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Images can be mid-aligned.

Copy link
Contributor

@Jay-o-Way Jay-o-Way left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wanna say that this document does not follow MS Learn style/formatting guidelines.

Some examples: (not limited to)

  • UI elements, like menu items, dialog names, and names of text boxes, should be in bold text.
  • Keys and keyboard shortcuts: use "select" and <kbd> tags
  • Empty lines between headers, lists, code blocks etc.
  • Each Markdown file must have one and only one H1 heading.
  • Spelling, please
  • Don't use bold as an alternative for a header

@dipeshmsft
Copy link
Member Author

@Jay-o-Way

I just wanna say that this document does not follow MS Learn style/formatting guidelines.

This document follows the API Spec template provided in the repo: https://github.com/microsoft/WindowsAppSDK/blob/main/specs/spec_template.md

I will take a look at rest of the formatting issues and update the spec accordingly.

@Jay-o-Way
Copy link
Contributor

This document follows the API Spec template provided in the repo:

😂 Hasn't been touched in at least 5 years though...

@d2phap
Copy link

d2phap commented Nov 14, 2025

@dipeshmsft Does it support KeyboardAccelerators? I don't see it mentioned here and no screenshot, too

@riverar
Copy link
Contributor

riverar commented Nov 21, 2025

@dipeshmsft

"Compress to ZIP" scenario may not be the best scenario for SplitMenuFlyoutItem and maybe more suited for MenuFlyoutSubItem.

I would like to draw your attention to the Paste example, where there are different ways of performing the paste - "Paste as Text", "Paste with Merge Formatting", "Paste with Source Formatting", etc. This is one of the true examples of what we are trying to achieve using this control. If there are multiple ways of performing one operation and the app developer wants to set one as the default mode operation, those scenarios are the ones that we are trying to support using this control.

That makes more sense, thank you.

In the example of having a menu item "Email to John" and then inside that command having sub-menu items like "Slack to John", "Call John", this is geared towards the default mode of action for a user. Say it is by mail, so we show that in the primary part, and other parts of making contact are secondary, so they are put in the sub menu item.

I don't think this scenario makes sense, unless "Email to John" is renamed to, say, "Tell John" with sub-menu items "Tell John via Email", "Tell John via SMS", etc.

In the light of the confusion this is creating I will go ahead and modify the usage examples in the API spec.

Thanks, I checked and didn't see new images/examples. Are you still working on that?

@dipeshmsft
Copy link
Member Author

Thanks, I checked and didn't see new images/examples. Are you still working on that?

After further discussion, we decided to remove the scenario as an example for this control.

@dipeshmsft
Copy link
Member Author

@d2phap
Keyboard accelerator is supported here. However, the visibility is disabled by default. However, visibility as a tooltip can be enabled at the developer's end.

@d2phap
Copy link

d2phap commented Dec 6, 2025

@dipeshmsft I hope it has an option to show the hotkey, customize the hotkey text, similar to the WinForms's MenuStrip:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: API Review - Gathering Feedback

Development

Successfully merging this pull request may close these issues.

8 participants