You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2026/07/15 23:03:09 UTC
(superset) branch chore/enable-jsx-a11y-no-static-element-interactions created (now de11a415d26)
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a change to branch chore/enable-jsx-a11y-no-static-element-interactions
in repository https://gitbox.apache.org/repos/asf/superset.git
at de11a415d26 chore(a11y): enable jsx-a11y/no-static-element-interactions as error
This branch includes the following new commits:
new de11a415d26 chore(a11y): enable jsx-a11y/no-static-element-interactions as error
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(superset) 01/01: chore(a11y): enable jsx-a11y/no-static-element-interactions as error
Posted by ru...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch chore/enable-jsx-a11y-no-static-element-interactions
in repository https://gitbox.apache.org/repos/asf/superset.git
commit de11a415d26d7a898cdc8e820983cb123f34a93c
Author: Evan Rusackas <ev...@rusackas.com>
AuthorDate: Wed Jul 15 16:02:23 2026 -0700
chore(a11y): enable jsx-a11y/no-static-element-interactions as error
Continues the incremental jsx-a11y rollout (follows #42006, #42009,
#42078). All 7 remaining violations were pure event-boundary wrappers
(divs/spans whose only handler is stopPropagation) or test scaffolding
where adding a role would be semantically wrong — suppressed with an
inline eslint-disable and an explanatory comment rather than restructured.
Co-Authored-By: Claude Sonnet 5 <no...@anthropic.com>
---
superset-frontend/oxlint.json | 6 +-----
.../src/components/ModalTrigger/ModalTrigger.test.tsx | 2 ++
.../superset-ui-core/src/components/ModalTrigger/index.tsx | 3 +++
.../SqlEditorTabHeader/SqlEditorTabHeader.test.tsx | 2 ++
.../components/TableExploreTree/TreeNodeRenderer.tsx | 14 ++++++++++++++
5 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/superset-frontend/oxlint.json b/superset-frontend/oxlint.json
index 876a0d9cab8..2510baf7396 100644
--- a/superset-frontend/oxlint.json
+++ b/superset-frontend/oxlint.json
@@ -221,11 +221,7 @@
"jsx-a11y/no-noninteractive-element-to-interactive-role": "error",
"jsx-a11y/no-noninteractive-tabindex": "error",
"jsx-a11y/no-redundant-roles": "error",
- // TODO: Graduate to "error" — remaining violations are event-boundary
- // wrappers (divs/spans whose handlers only stopPropagation) and test
- // scaffolding where adding a role is semantically wrong. Needs a
- // dedicated pass; see PR enabling the other jsx-a11y interactive rules.
- "jsx-a11y/no-static-element-interactions": "off",
+ "jsx-a11y/no-static-element-interactions": "error",
"jsx-a11y/role-has-required-aria-props": "error",
"jsx-a11y/role-supports-aria-props": "error",
"jsx-a11y/scope": "error",
diff --git a/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.test.tsx
index 95854892212..31d2e0f83aa 100644
--- a/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.test.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.test.tsx
@@ -80,6 +80,8 @@ test('stops propagation of navigation keys to parent elements', async () => {
const handleParentKeyDown = jest.fn();
render(
+ // Test-only harness div asserting keydown doesn't bubble past the modal.
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div onKeyDown={handleParentKeyDown}>
<ModalTrigger
triggerNode={<span>Trigger</span>}
diff --git a/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/index.tsx b/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/index.tsx
index 2e94712f513..66976799aba 100644
--- a/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/index.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/index.tsx
@@ -156,6 +156,9 @@ export const ModalTrigger = forwardRef(
draggableConfig={draggableConfig}
destroyOnHidden={destroyOnHidden}
>
+ {/* Pure event-boundary wrapper: only stops menu-navigation keys
+ from bubbling out of the modal, not itself interactive. */}
+ {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
<div
style={{ display: 'contents' }}
onKeyDown={e => {
diff --git a/superset-frontend/src/SqlLab/components/SqlEditorTabHeader/SqlEditorTabHeader.test.tsx b/superset-frontend/src/SqlLab/components/SqlEditorTabHeader/SqlEditorTabHeader.test.tsx
index 0452f642310..686cf730b65 100644
--- a/superset-frontend/src/SqlLab/components/SqlEditorTabHeader/SqlEditorTabHeader.test.tsx
+++ b/superset-frontend/src/SqlLab/components/SqlEditorTabHeader/SqlEditorTabHeader.test.tsx
@@ -322,6 +322,8 @@ test('does not leak tab-editing keystrokes from the rename input to the surround
const onContainerKeyDown = jest.fn();
const store = mockStore(initialState);
render(
+ // Test-only harness div asserting keydown doesn't leak past the tab header.
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div onKeyDown={onContainerKeyDown}>
<SqlEditorTabHeader queryEditor={defaultQueryEditor} />
</div>,
diff --git a/superset-frontend/src/SqlLab/components/TableExploreTree/TreeNodeRenderer.tsx b/superset-frontend/src/SqlLab/components/TableExploreTree/TreeNodeRenderer.tsx
index af423f12b5f..195f1636a35 100644
--- a/superset-frontend/src/SqlLab/components/TableExploreTree/TreeNodeRenderer.tsx
+++ b/superset-frontend/src/SqlLab/components/TableExploreTree/TreeNodeRenderer.tsx
@@ -184,6 +184,9 @@ const TreeNodeRenderer: React.FC<TreeNodeRendererProps> = ({
<ColumnElement
column={data.columnData}
actions={
+ // Pure event-boundary wrapper: only stops the click/keydown from
+ // reaching the row's select handler, not itself interactive.
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
<span
className="col-copy-action"
onClick={e => e.stopPropagation()}
@@ -205,6 +208,11 @@ const TreeNodeRenderer: React.FC<TreeNodeRendererProps> = ({
}
return (
+ // react-arborist's row wrapper (an ancestor of this element) already
+ // supplies role="treeitem" and roving tabIndex/keyboard nav; this div
+ // just forwards clicks/keys to node.select()/toggle(), so adding its
+ // own role would create a nested-interactive-role anti-pattern.
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div
className="tree-node"
style={style}
@@ -245,6 +253,9 @@ const TreeNodeRenderer: React.FC<TreeNodeRendererProps> = ({
{highlightText(data.name, searchTerm)}
</Typography.Text>
{identifier === 'schema' && (
+ // Pure event-boundary wrapper: only stops the click/keydown from
+ // reaching the row's select handler, not itself interactive.
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div
className="side-action-container"
onClick={e => e.stopPropagation()}
@@ -313,6 +324,9 @@ const TreeNodeRenderer: React.FC<TreeNodeRendererProps> = ({
const isPinned = pinnedTableKeys.has(tableKey);
const selectStar = selectStarMap[tableKey];
return (
+ // Pure event-boundary wrapper: only stops the click/keydown from
+ // reaching the row's select handler, not itself interactive.
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div
className="side-action-container"
onClick={e => e.stopPropagation()}