Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 10x 10x 65x 65x 65x 14x | import { MouseEvent } from "react";
import { Stack } from "@mui/material";
import { FunnelSimpleIcon, XIcon } from "@phosphor-icons/react";
import GiveButton from "@shared/Button/GiveButton";
import GiveIconButton from "@shared/IconButton/GiveIconButton";
import { styled } from "@theme/v2/Provider";
export const CLEAR_FILTERS_ARIA_LABEL = "Clear filters";
type Props = {
/** `useFilterButton`'s label — "Filter", or "Filters (N)" once applied. */
label: string;
filtersAmount: number;
onOpen: () => void;
/** `useFilterButton`'s reset. */
onClear: (event?: MouseEvent<HTMLElement>) => void;
testId: string;
};
/**
* The desktop Filter control shared by the Event Detail Transactions and Tickets
* tabs (frame 8238-63616, "Table Options"): the ghost pill with the funnel, and
* — once a filter is applied — a small ✕ chip after the count that clears it in
* place. Without the chip, a filter that matched nothing left the user with an
* empty list and only the panel's own Clear All as a way out.
*
* The chip is a sibling of the pill, not a child: a control nested inside a
* button is invalid markup and reads to a screen reader as a button in a
* button. Two real buttons also give Tab two stops and Enter / Space for free.
*/
const EventListFilterButton = ({
label,
filtersAmount,
onOpen,
onClear,
testId,
}: Props) => {
const isApplied = filtersAmount > 0;
return (
<Stack direction="row" alignItems="center">
<FilterButton
variant="ghost"
color="light"
size="large"
startIcon={<FunnelSimpleIcon size={18} />}
data-testid={testId}
onClick={onOpen}
label={label}
/>
{isApplied && (
<ClearButton
Icon={XIcon}
variant="ghost"
size="extraSmall"
aria-label={CLEAR_FILTERS_ARIA_LABEL}
data-testid={`${testId}-clear`}
onClick={onClear}
/>
)}
</Stack>
);
};
export default EventListFilterButton;
// Matches the Export control beside it — frame 7397-90412 puts both on one 42px
// row.
const FilterButton = styled(GiveButton)(() => ({
borderRadius: "40px",
height: "42px",
whiteSpace: "nowrap",
}));
// Frame 8238-63616 "Clear Button": a 16px ✕ on a 2px pad of darken-5. The pill
// carries 20px of end padding, so the negative margin is what leaves the
// frame's 8px between the count and the chip.
const ClearButton = styled(GiveIconButton)(({ theme }) => ({
marginLeft: "-12px",
padding: "2px",
borderRadius: "38px",
backgroundColor: theme.palette.primitive?.transparent["darken-5"],
"&:hover, &:focus-visible": {
backgroundColor: theme.palette.primitive?.transparent["darken-10"],
},
}));
|