refactor(filters): extract the chip row from ActiveFilterChips (#188)

This commit is contained in:
2026-08-25 15:23:25 -05:00
parent 1d7f928c48
commit 918d6eeab9
@@ -0,0 +1,48 @@
import Tag from 'antd/es/tag';
import Button from 'antd/es/button';
import type { Chip } from './dimension';
type Props = Readonly<{
chips: Chip[];
onClear: () => void;
}>;
/**
* The removable filter row.
*
* Knows nothing about filters — it is handed chips and renders them. Every
* decision about what a chip says, what colour it is and what removing it does
* belongs to the dimension that produced it.
*/
export default function FilterChips({ chips, onClear }: Props) {
if (!chips.length) return null;
return (
// Named as a group so this row's Clear all stays distinguishable from the
// identically-labelled one in the drawer's footer.
<div className="active-filter-chips" role="group" aria-label="Active filters">
{chips.map((chip) => (
<Tag
key={chip.key}
// Undefined for every filter with no colour of its own, which is
// antd's default. The close icon below inherits the tag's text
// colour, so a coloured chip gets a matching cross.
color={chip.color}
closable
onClose={(event) => {
event.preventDefault();
chip.onRemove();
}}
// antd renders the close control as an icon with no text, so name it
// for screen readers and for anything driving the page by role.
closeIcon={
<span role="button" aria-label={`Remove filter ${chip.label.split(' / ').pop()}`}>×</span>
}
>
{chip.label}
</Tag>
))}
<Button size="small" type="link" onClick={onClear}>Clear all</Button>
</div>
);
}