fix(listview): normalize select option + match AntD dropdown styles

Normalize selected option to plain {label: string, value} before passing
to onSelect — matches original SelectFilter behaviour and prevents
'Converting circular structure to JSON' when emotion-styled ReactNode
labels are serialized to URL query params.

Style OptionItem to match AntD Select dropdown exactly: colorBgElevated
container, fontSize (not fontSizeSM), colorText always (not colorPrimary
on selected), colorFillTertiary hover, borderRadiusSM on items, 32px
height with sizeUnit padding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kasiazjc
2026-05-15 16:42:05 +00:00
committed by Amin Ghadersohi
parent 1b5a31a203
commit 6224bc7aec

View File

@@ -59,7 +59,7 @@ const PanelContainer = styled.div`
flex-direction: column;
border-radius: ${theme.borderRadius}px;
overflow: hidden;
background: ${theme.colorBgContainer};
background: ${theme.colorBgElevated};
box-shadow: ${theme.boxShadowSecondary};
padding: ${theme.sizeUnit * 2}px;
@@ -84,16 +84,17 @@ const OptionItem = styled.li<{ $active: boolean }>`
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 ${theme.sizeUnit * 3}px;
min-height: 35px;
padding: ${theme.sizeUnit}px ${theme.sizeUnit * 3}px;
min-height: 32px;
cursor: pointer;
font-size: ${theme.fontSizeSM}px;
color: ${$active ? theme.colorPrimary : theme.colorText};
font-size: ${theme.fontSize}px;
color: ${theme.colorText};
background: ${$active ? theme.colorPrimaryBg : 'transparent'};
border-radius: ${theme.borderRadiusSM}px;
transition: background 0.15s;
&:hover {
background: ${$active ? theme.colorPrimaryBgHover : theme.colorFillAlter};
background: ${$active ? theme.colorPrimaryBgHover : theme.colorFillTertiary};
}
`}
`;
@@ -214,7 +215,16 @@ function CompactSelectPanel(
const handleSelect = (opt: SelectOption) => {
const isDeselect = selectedOption?.value === opt.value;
const next = isDeselect ? undefined : opt;
// Normalize to a plain object so the value can be safely serialized to
// URL query params without circular-reference errors from emotion metadata
// on styled ReactNode labels.
const next = isDeselect
? undefined
: {
label:
typeof opt.label === 'string' ? opt.label : String(opt.value ?? ''),
value: opt.value,
};
setSelectedOption(next);
onSelect(next, isDeselect);
onClose?.();