From d4baf19c454492d4c383f1fc08f5946631c9f0e3 Mon Sep 17 00:00:00 2001 From: Fedo Hagge-Kubat Date: Mon, 2 Mar 2026 17:47:55 +0100 Subject: [PATCH 1/3] =?UTF-8?q?fix(a11y):=20WCAG=201.4.4=20=E2=80=94=20rep?= =?UTF-8?q?lace=20hardcoded=20px=20with=20theme=20tokens=20for=20text=20re?= =?UTF-8?q?size?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace hardcoded 12px font-sizes with inherit/theme tokens in error messages - Convert fixed height:24px to min-height:24px in SliceHeader controls - Replace px-based line-heights with unitless values (1, 1.2, 1.5) - Remove fixed max-width on brand text, add flex-wrap for nav wrapping at zoom - Replace fontSize:22 with theme.fontSizeXL in fullscreen icon - Replace font-size:14px with theme.fontSize in ScheduleQueryButton - Replace fontSize:'12px' with theme.fontSizeSM in SparklineCell tooltip - Replace font-size:12px with theme.fontSizeSM in CustomizationsBadge icon Co-Authored-By: Claude Opus 4.6 --- .../components/RunQueryActionButton/index.tsx | 2 +- .../components/ScheduleQueryButton/index.tsx | 2 +- .../SqlLab/components/TabbedSqlEditors/index.tsx | 2 +- .../components/CustomizationsBadge/index.tsx | 2 +- .../dashboard/components/SliceHeader/index.tsx | 2 +- .../components/SliceHeaderControls/index.tsx | 5 +++-- .../DateFilterControl/DateFilterLabel.tsx | 6 +++--- .../components/controls/NumberControl/index.tsx | 9 +++++++++ .../components/controls/TextControl/index.tsx | 9 +++++++++ .../databases/DatabaseModal/SSHTunnelForm.tsx | 15 +++++++++++++++ superset-frontend/src/features/home/Menu.tsx | 3 ++- superset-frontend/src/features/home/SubMenu.tsx | 4 ++-- .../components/SparklineCell/SparklineCell.tsx | 2 +- 13 files changed, 49 insertions(+), 14 deletions(-) diff --git a/superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx b/superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx index 4353951a715b..62b102248f30 100644 --- a/superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx +++ b/superset-frontend/src/SqlLab/components/RunQueryActionButton/index.tsx @@ -79,7 +79,7 @@ const onClick = ( const StyledButton = styled.span` button { - line-height: 13px; + line-height: 1; min-width: auto !important; padding: 0 ${({ theme }) => theme.sizeUnit * 3}px 0 ${({ theme }) => theme.sizeUnit * 2}px; diff --git a/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx b/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx index bf1b0ab2a2be..bb8ba57a1492 100644 --- a/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx +++ b/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx @@ -108,7 +108,7 @@ export const StyledButtonComponent = styled(Button)` background: none; text-transform: none; padding: 0px; - font-size: 14px; + font-size: ${theme.fontSize}px; font-weight: ${theme.fontWeightNormal}; margin-left: 0; &:disabled { diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx index f03f399583cd..235274a491b8 100644 --- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx +++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx @@ -81,7 +81,7 @@ const StyledEditableTabs = styled(EditableTabs)` `; const StyledTab = styled.span` - line-height: 24px; + line-height: 1.5; `; const TabTitle = styled.span` diff --git a/superset-frontend/src/dashboard/components/CustomizationsBadge/index.tsx b/superset-frontend/src/dashboard/components/CustomizationsBadge/index.tsx index dbe3c91c8c72..2cf109eb6dbc 100644 --- a/superset-frontend/src/dashboard/components/CustomizationsBadge/index.tsx +++ b/superset-frontend/src/dashboard/components/CustomizationsBadge/index.tsx @@ -83,7 +83,7 @@ const StyledTag = styled(Tag)` vertical-align: middle; color: ${theme.colorTextSecondary}; margin-right: ${theme.sizeUnit * 0.5}px; - font-size: 12px; + font-size: ${theme.fontSizeSM}px; &:hover { color: ${theme.colorText}; } diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx index be29e3c8e89f..c38b17fcd1af 100644 --- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx +++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx @@ -100,7 +100,7 @@ const ChartHeaderStyles = styled.div` & > .header-controls { display: flex; align-items: center; - height: 24px; + min-height: 24px; } .dropdown.btn-group { diff --git a/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx b/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx index 9fcf2ab00964..04132d7dd9a4 100644 --- a/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx +++ b/superset-frontend/src/dashboard/components/SliceHeaderControls/index.tsx @@ -67,7 +67,7 @@ const RefreshTooltip = styled.div` height: auto; margin: ${theme.sizeUnit}px 0; color: ${theme.colorTextLabel}; - line-height: 21px; + line-height: 1.5; display: flex; flex-direction: column; align-items: flex-start; @@ -558,7 +558,8 @@ const SliceHeaderControls = ( <> {isFullSize && ( { props.handleToggleFullSize(); }} diff --git a/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterLabel.tsx b/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterLabel.tsx index 3aa6a1415d3a..d67eddcff124 100644 --- a/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterLabel.tsx +++ b/superset-frontend/src/explore/components/controls/DateFilterControl/DateFilterLabel.tsx @@ -79,15 +79,15 @@ const ContentStyleWrapper = styled.div` .control-label { font-size: ${theme.fontSizeSM}px; - line-height: 16px; + line-height: 1.2; margin: 8px 0; } .section-title { font-style: normal; font-weight: ${theme.fontWeightStrong}; - font-size: 15px; - line-height: 24px; + font-size: ${theme.fontSize}px; + line-height: 1.5; margin-bottom: 8px; } diff --git a/superset-frontend/src/explore/components/controls/NumberControl/index.tsx b/superset-frontend/src/explore/components/controls/NumberControl/index.tsx index ec2eb7c9c6e9..6ed042743751 100644 --- a/superset-frontend/src/explore/components/controls/NumberControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/NumberControl/index.tsx @@ -85,6 +85,15 @@ export default function NumberControl({ disabled={disabled} aria-label={rest.label} /> + {hasErrors && ( + + {rest.validationErrors!.join('. ')} + + )} ); } diff --git a/superset-frontend/src/explore/components/controls/TextControl/index.tsx b/superset-frontend/src/explore/components/controls/TextControl/index.tsx index 805d3d90eb79..c437c2012b84 100644 --- a/superset-frontend/src/explore/components/controls/TextControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/TextControl/index.tsx @@ -117,6 +117,15 @@ export default class TextControl< disabled={this.props.disabled} aria-label={this.props.label} /> + {hasErrors && ( + + {this.props.validationErrors!.join('. ')} + + )} ); } diff --git a/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx b/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx index ed47ed1952e9..fe4addc2b904 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx +++ b/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx @@ -79,6 +79,11 @@ const SSHTunnelForm = ({ onChange={onSSHTunnelParametersChange} data-test="ssh-tunnel-server_address-input" /> + {fieldError('server_address', db?.ssh_tunnel?.server_address) && ( + + {t('SSH Host is required')} + + )} @@ -94,6 +99,11 @@ const SSHTunnelForm = ({ onChange={onSSHTunnelParametersChange} data-test="ssh-tunnel-server_port-input" /> + {fieldError('server_port', db?.ssh_tunnel?.server_port) && ( + + {t('SSH Port is required')} + + )} @@ -111,6 +121,11 @@ const SSHTunnelForm = ({ onChange={onSSHTunnelParametersChange} data-test="ssh-tunnel-username-input" /> + {fieldError('username', db?.ssh_tunnel?.username) && ( + + {t('Username is required')} + + )} diff --git a/superset-frontend/src/features/home/Menu.tsx b/superset-frontend/src/features/home/Menu.tsx index 1849e8a2e2d6..a34eaa9217ef 100644 --- a/superset-frontend/src/features/home/Menu.tsx +++ b/superset-frontend/src/features/home/Menu.tsx @@ -74,7 +74,7 @@ const StyledBrandText = styled.div` justify-content: center; span { - max-width: ${theme.sizeUnit * 58}px; + max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; @@ -175,6 +175,7 @@ const StyledRow = styled(Row)` const StyledCol = styled(Col)` ${({ theme }) => css` display: flex; + flex-wrap: wrap; gap: ${theme.sizeUnit * 4}px; flex-wrap: wrap; `} diff --git a/superset-frontend/src/features/home/SubMenu.tsx b/superset-frontend/src/features/home/SubMenu.tsx index f71892fb5014..fe3fd23fc060 100644 --- a/superset-frontend/src/features/home/SubMenu.tsx +++ b/superset-frontend/src/features/home/SubMenu.tsx @@ -54,7 +54,7 @@ const StyledHeader = styled.div<{ backgroundColor?: string }>` text-align: left; font-size: 18px; display: inline-block; - line-height: ${({ theme }) => theme.sizeUnit * 9}px; + line-height: 1.5; } .nav-right { display: flex; @@ -91,7 +91,7 @@ const StyledHeader = styled.div<{ backgroundColor?: string }>` .menu > .ant-menu { padding-left: ${({ theme }) => theme.sizeUnit * 5}px; - line-height: ${({ theme }) => theme.sizeUnit * 5}px; + line-height: 1.5; .ant-menu-item { border-radius: ${({ theme }) => theme.borderRadius}px; diff --git a/superset-frontend/src/visualizations/TimeTable/components/SparklineCell/SparklineCell.tsx b/superset-frontend/src/visualizations/TimeTable/components/SparklineCell/SparklineCell.tsx index 4b89c035780d..7b5a0ce9cac0 100644 --- a/superset-frontend/src/visualizations/TimeTable/components/SparklineCell/SparklineCell.tsx +++ b/superset-frontend/src/visualizations/TimeTable/components/SparklineCell/SparklineCell.tsx @@ -231,7 +231,7 @@ const SparklineCell = ({
({ color: theme.colorTextSecondary, - fontSize: '12px', + fontSize: `${theme.fontSizeSM}px`, })} > {formatTime( From f19c1a6788d25cf1dfd0530c64564936a55aba68 Mon Sep 17 00:00:00 2001 From: Fedo Hagge-Kubat Date: Thu, 9 Apr 2026 21:12:41 +0200 Subject: [PATCH 2/3] fix(a11y): remove accidentally included 3.3.1 error validation code and fix remaining px values --- .../components/controls/NumberControl/index.tsx | 9 --------- .../components/controls/TextControl/index.tsx | 9 --------- .../databases/DatabaseModal/SSHTunnelForm.tsx | 15 --------------- 3 files changed, 33 deletions(-) diff --git a/superset-frontend/src/explore/components/controls/NumberControl/index.tsx b/superset-frontend/src/explore/components/controls/NumberControl/index.tsx index 6ed042743751..ec2eb7c9c6e9 100644 --- a/superset-frontend/src/explore/components/controls/NumberControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/NumberControl/index.tsx @@ -85,15 +85,6 @@ export default function NumberControl({ disabled={disabled} aria-label={rest.label} /> - {hasErrors && ( - - {rest.validationErrors!.join('. ')} - - )} ); } diff --git a/superset-frontend/src/explore/components/controls/TextControl/index.tsx b/superset-frontend/src/explore/components/controls/TextControl/index.tsx index c437c2012b84..805d3d90eb79 100644 --- a/superset-frontend/src/explore/components/controls/TextControl/index.tsx +++ b/superset-frontend/src/explore/components/controls/TextControl/index.tsx @@ -117,15 +117,6 @@ export default class TextControl< disabled={this.props.disabled} aria-label={this.props.label} /> - {hasErrors && ( - - {this.props.validationErrors!.join('. ')} - - )}
); } diff --git a/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx b/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx index fe4addc2b904..ed47ed1952e9 100644 --- a/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx +++ b/superset-frontend/src/features/databases/DatabaseModal/SSHTunnelForm.tsx @@ -79,11 +79,6 @@ const SSHTunnelForm = ({ onChange={onSSHTunnelParametersChange} data-test="ssh-tunnel-server_address-input" /> - {fieldError('server_address', db?.ssh_tunnel?.server_address) && ( - - {t('SSH Host is required')} - - )} @@ -99,11 +94,6 @@ const SSHTunnelForm = ({ onChange={onSSHTunnelParametersChange} data-test="ssh-tunnel-server_port-input" /> - {fieldError('server_port', db?.ssh_tunnel?.server_port) && ( - - {t('SSH Port is required')} - - )} @@ -121,11 +111,6 @@ const SSHTunnelForm = ({ onChange={onSSHTunnelParametersChange} data-test="ssh-tunnel-username-input" /> - {fieldError('username', db?.ssh_tunnel?.username) && ( - - {t('Username is required')} - - )} From f84904c2653d247cac68d1eb459ee40f30797535 Mon Sep 17 00:00:00 2001 From: Kolja Date: Thu, 7 May 2026 18:31:34 +0200 Subject: [PATCH 3/3] =?UTF-8?q?fix(a11y):=20WCAG=201.4.4=20=E2=80=94=20dro?= =?UTF-8?q?p=20remaining=20hardcoded=20px=20font=20sizes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses bot review on PR #39235: - ScheduleQueryButton dropped `font-size: ${theme.fontSize}px;` so the button now inherits surrounding typography. Hardcoding the base font size in pixels defeats the resize-text goal because the rule overrides whatever default size the user picked in their browser. - SparklineCell timestamp switched from `${theme.fontSizeSM}px` to `0.85em`, so the secondary text scales with the surrounding cell font size when the user resizes browser text. - Menu.tsx: removed the duplicate `flex-wrap: wrap` declaration in StyledCol — earlier diff added a second copy of the same rule. --- .../src/SqlLab/components/ScheduleQueryButton/index.tsx | 1 - superset-frontend/src/features/home/Menu.tsx | 1 - .../TimeTable/components/SparklineCell/SparklineCell.tsx | 5 ++++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx b/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx index bb8ba57a1492..020c88c4080b 100644 --- a/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx +++ b/superset-frontend/src/SqlLab/components/ScheduleQueryButton/index.tsx @@ -108,7 +108,6 @@ export const StyledButtonComponent = styled(Button)` background: none; text-transform: none; padding: 0px; - font-size: ${theme.fontSize}px; font-weight: ${theme.fontWeightNormal}; margin-left: 0; &:disabled { diff --git a/superset-frontend/src/features/home/Menu.tsx b/superset-frontend/src/features/home/Menu.tsx index a34eaa9217ef..439e67189755 100644 --- a/superset-frontend/src/features/home/Menu.tsx +++ b/superset-frontend/src/features/home/Menu.tsx @@ -177,7 +177,6 @@ const StyledCol = styled(Col)` display: flex; flex-wrap: wrap; gap: ${theme.sizeUnit * 4}px; - flex-wrap: wrap; `} `; diff --git a/superset-frontend/src/visualizations/TimeTable/components/SparklineCell/SparklineCell.tsx b/superset-frontend/src/visualizations/TimeTable/components/SparklineCell/SparklineCell.tsx index 7b5a0ce9cac0..a4fffac1602a 100644 --- a/superset-frontend/src/visualizations/TimeTable/components/SparklineCell/SparklineCell.tsx +++ b/superset-frontend/src/visualizations/TimeTable/components/SparklineCell/SparklineCell.tsx @@ -231,7 +231,10 @@ const SparklineCell = ({
({ color: theme.colorTextSecondary, - fontSize: `${theme.fontSizeSM}px`, + // Use em so secondary timestamp scales with the + // surrounding cell font-size when users adjust + // browser default text size (WCAG 1.4.4). + fontSize: '0.85em', })} > {formatTime(