Skip to content

[fix]: menu-items programmatically added to menu-list do not properl…#35765

Open
eljefe223 wants to merge 1 commit intomicrosoft:masterfrom
eljefe223:users/jes/menu-list-programmatically-adding-data-indent
Open

[fix]: menu-items programmatically added to menu-list do not properl…#35765
eljefe223 wants to merge 1 commit intomicrosoft:masterfrom
eljefe223:users/jes/menu-list-programmatically-adding-data-indent

Conversation

@eljefe223
Copy link
Contributor

Previous Behavior

In the following example code, the data-indent attribute value is always 0.

const menuList = document.querySelector("fluent-menu-list");
const ITEMS = [
  "item 1",
  "item 2",
  "item 3",
];

ITEMS.forEach(item => {
  const menuItem = document.createElement("fluent-menu-item");
  menuItem.role = "menuitemradio";
  menuItem.textContent = item;
  menuList.append(menuItem);
});

The same issue also exist if you append the items to a DocumentFragment first then append the DocumentFragment to the menu list.

Current workaround is:

const menuList = document.querySelector("fluent-menu-list");
const ITEMS = [
  "item 1",
  "item 2",
  "item 3",
];
const html = [];

ITEMS.forEach(item => {
  html.push(`
    <fluent-menu-item role="menuitemradio">
      ${item}
    </fluent-menu-item>
  `);
});

menuList.innerHTML = html.join("");

New Behavior

Root cause: FAST's @attr decorator defers DOM attribute reflection via Updates.enqueue() (async microtask). When menu items are created programmatically with document.createElement() and the role property is set, the internal property value updates immediately but setAttribute('role', ...) is deferred. When setItems() runs in response to slotchange, el.getAttribute('role') returns stale/missing values, causing elementIndent() to always return 0.
With innerHTML, the HTML parser sets attributes directly before element upgrade, so getAttribute('role') works immediately.

Related Issue(s)

  • Fixes #

@eljefe223 eljefe223 requested a review from a team as a code owner February 19, 2026 22:50
@github-actions
Copy link

📊 Bundle size report

✅ No changes found

@github-actions
Copy link

Pull request demo site: URL

@@ -0,0 +1,7 @@
{

Choose a reason for hiding this comment

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

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-web-components/Accordion 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/Accordion. - Dark Mode.normal.chromium_1.png 3154 Changed
vr-tests-web-components/Avatar 2 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/Avatar. - Dark Mode.normal.chromium_1.png 298 Changed
vr-tests-web-components/Avatar. - Dark Mode.normal.chromium.png 10380 Changed
vr-tests-web-components/MenuList 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/MenuList. - Dark Mode.normal.chromium.png 498 Changed
vr-tests-web-components/RadioGroup 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/RadioGroup. - Dark Mode.normal.chromium_1.png 89 Changed
vr-tests-web-components/TextInput 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/TextInput. - Dark Mode.normal.chromium_1.png 288 Changed

There were 1 duplicate changes discarded. Check the build logs for more information.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments