fix: Highlight outline of numerical range and time range filters (#34705)

This commit is contained in:
Kamil Gabryjelski
2025-08-19 14:16:03 +02:00
committed by GitHub
parent 852adaa6cc
commit 6969f2cf7a
3 changed files with 53 additions and 38 deletions

View File

@@ -82,6 +82,7 @@ export const FilterItem = styled.button`
background: none;
outline: none;
width: 100%;
color: inherit;
&::-moz-focus-inner {
border: 0;

View File

@@ -25,6 +25,7 @@ import {
styled,
useTheme,
t,
css,
} from '@superset-ui/core';
import { useCallback, useEffect, useMemo, useState, useRef } from 'react';
import { FilterBarOrientation } from 'src/dashboard/types';
@@ -70,7 +71,7 @@ const SliderWrapper = styled.div`
const TooltipContainer = styled.div`
${({ theme }) => `
position: absolute;
top: -${theme.sizeUnit * 10}px;
top: -${theme.sizeUnit * 6}px;
right: 0px;
z-index: 100;
display: flex;
@@ -85,42 +86,40 @@ const TooltipContainer = styled.div`
const HorizontalLayout = styled.div`
${({ theme }) => `
display: flex;
flex-direction: column;
gap: ${theme.sizeUnit * 4}px;
width: 100%;
align-items: center;
.controls-container {
.slider-wrapper {
display: flex;
align-items: center;
gap: ${theme.sizeUnit * 4}px;
width: 100%;
.slider-wrapper {
display: flex;
align-items: center;
flex: 2;
}
.slider-container {
flex: 1;
min-width: 180px;
}
.inputs-container {
min-width: 160px;
max-width: 200px;
}
flex: 2;
}
.message-container {
width: 100%;
text-align: center;
padding-top: ${theme.sizeUnit * 2}px;
.slider-container {
flex: 1;
min-width: 180px;
}
.inputs-container {
min-width: 160px;
max-width: 200px;
}
`}
`;
const FocusContainer = styled.div`
${({ theme }) => `
border-radius: ${theme.borderRadius}px;
transition: box-shadow ${theme.motionDurationMid} ease-in-out;
&:focus {
box-shadow: 0 0 0 2px ${theme.colorPrimary};
}
&:focus-visible {
outline: none;
}`}
`;
const numberFormatter = getNumberFormatter(NumberFormats.SMART_NUMBER);
const getLabel = (
@@ -579,7 +578,6 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) {
const renderInputs = () => (
<Wrapper
tabIndex={-1}
ref={inputRef}
onFocus={setFocusedFilter}
onBlur={unsetFocusedFilter}
onMouseEnter={setHoveredFilter}
@@ -627,8 +625,8 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) {
<FormItem aria-labelledby={`filter-name-${formData.nativeFilterId}`}>
{filterBarOrientation === FilterBarOrientation.Horizontal &&
!isOverflowingFilterBar ? (
<HorizontalLayout>
<div className="controls-container">
<FocusContainer ref={inputRef} tabIndex={-1}>
<HorizontalLayout>
<InfoTooltip />
{(rangeDisplayMode === RangeDisplayMode.Slider ||
rangeDisplayMode === RangeDisplayMode.SliderAndInput) && (
@@ -640,8 +638,8 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) {
rangeDisplayMode === RangeDisplayMode.SliderAndInput) && (
<div className="inputs-container">{renderInputs()}</div>
)}
</div>
</HorizontalLayout>
</HorizontalLayout>
</FocusContainer>
) : (
<>
<div style={{ position: 'relative' }}>
@@ -650,12 +648,21 @@ export default function RangeFilterPlugin(props: PluginFilterRangeProps) {
<InfoTooltip />
</TooltipContainer>
)}
{(rangeDisplayMode === RangeDisplayMode.Slider ||
rangeDisplayMode === RangeDisplayMode.SliderAndInput) &&
renderSlider()}
{(rangeDisplayMode === RangeDisplayMode.Input ||
rangeDisplayMode === RangeDisplayMode.SliderAndInput) &&
renderInputs()}
<FocusContainer
ref={inputRef}
tabIndex={-1}
css={css`
padding-top: 1px;
margin-top: -1px;
`}
>
{(rangeDisplayMode === RangeDisplayMode.Slider ||
rangeDisplayMode === RangeDisplayMode.SliderAndInput) &&
renderSlider()}
{(rangeDisplayMode === RangeDisplayMode.Input ||
rangeDisplayMode === RangeDisplayMode.SliderAndInput) &&
renderInputs()}
</FocusContainer>
<MessageDisplay />
</div>

View File

@@ -29,7 +29,7 @@ import { FilterPluginStyle } from '../common';
const TimeFilterStyles = styled(FilterPluginStyle)`
display: flex;
align-items: center;
overflow-x: auto;
overflow-x: visible;
& .ant-tag {
margin-right: 0;
@@ -62,6 +62,12 @@ const ControlContainer = styled.div<{
& > div {
width: 100%;
}
&:focus > div {
border-color: ${({ theme }) => theme.colorPrimary};
box-shadow: ${({ theme }) => `0 0 0 2px ${theme.controlOutline}`};
outline: 0;
}
`;
export default function TimeFilterPlugin(props: PluginFilterTimeProps) {
@@ -115,6 +121,7 @@ export default function TimeFilterPlugin(props: PluginFilterTimeProps) {
onBlur={unsetFocusedFilter}
onMouseEnter={setHoveredFilter}
onMouseLeave={unsetHoveredFilter}
tabIndex={-1}
>
<DateFilterComponent
value={filterState.value || NO_TIME_RANGE}