commit b06d57f3afb43a9f0eb50c830cf974276d8c63df
parent 4f49c8bca6f8beaf30de9e51b7a767036e9e6489
Author: hannajones <hjones@mozilla.com>
Date: Mon, 3 Nov 2025 19:54:04 +0000
Bug 1996980 - ensure tabindex on setting-control propagates to inner control element r=akulyk
Differential Revision: https://phabricator.services.mozilla.com/D270695
Diffstat:
2 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/browser/components/preferences/tests/chrome/test_setting_control_checkbox.html b/browser/components/preferences/tests/chrome/test_setting_control_checkbox.html
@@ -437,6 +437,73 @@
"Rendered with a setting"
);
});
+
+ add_task(async function testTabIndex() {
+ const PREF = "test.setting-control.tabindex";
+ const SETTING = "setting-control-tabindex";
+ await SpecialPowers.pushPrefEnv({
+ set: [[PREF, true]],
+ });
+ Preferences.addAll([{ id: PREF, type: "bool" }]);
+ Preferences.addSetting({
+ id: SETTING,
+ pref: PREF,
+ });
+ let itemConfig = { l10nId: LABEL_L10N_ID, id: SETTING };
+ let control = await renderTemplate(itemConfig);
+
+ // Create an element to help with testing keyboard interactions.
+ let focusTrap = document.createElement("button");
+ focusTrap.textContent = "before";
+ control.prepend(focusTrap);
+
+ ok(
+ !control.getAttribute("tabindex"),
+ "tabindex is not set on the setting-control initially."
+ );
+ ok(
+ !control.controlEl.getAttribute("tabindex"),
+ "tabindex is not set on the inner control element initially."
+ );
+ isnot(
+ document.activeElement,
+ control.controlEl,
+ "The control is not focused initially."
+ );
+
+ focusTrap.focus();
+ synthesizeKey("KEY_Tab", {});
+
+ is(
+ document.activeElement,
+ control.controlEl,
+ "The control element receives focus via keyboard interaction."
+ );
+
+ // Restore focus to the button.
+ focusTrap.focus();
+
+ control.setAttribute("tabindex", "-1");
+ await control.updateComplete;
+
+ is(
+ control.tabIndex,
+ -1,
+ "tabIndex property gets set on the setting-control."
+ );
+ is(
+ control.controlEl.getAttribute("tabindex"),
+ "-1",
+ "tabindex gets propagated to the control el."
+ );
+
+ synthesizeKey("KEY_Tab", {});
+ isnot(
+ document.activeElement,
+ control.controlEl,
+ "The control element no longer receives focus via keyboard interaction."
+ );
+ });
</script>
</head>
<body>
diff --git a/browser/components/preferences/widgets/setting-control/setting-control.mjs b/browser/components/preferences/widgets/setting-control/setting-control.mjs
@@ -67,6 +67,7 @@ export class SettingControl extends SettingElement {
value: {},
parentDisabled: { type: Boolean },
showEnableExtensionMessage: { type: Boolean },
+ tabIndex: { type: Number, reflect: true },
};
/**
@@ -349,6 +350,7 @@ export class SettingControl extends SettingElement {
<${tag}
${spread(controlProps)}
${ref(this.controlRef)}
+ tabindex=${ifDefined(this.tabIndex)}
>${controlChildren}${nestedSettings}</${tag}>`;
}
}