mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
fix(filters): make the whole filter option row clickable
The padding around an enum filter's checkbox/radio carried the hover cue but swallowed the click: the only element that toggles a Mantine Checkbox is its native <label>, which wraps its own text and nothing else. The row's padding and the gutter beside the input square lie outside it, so styling those on `root` produced an area that looked interactive and was not. Stretch a `::before` over the relatively-positioned root. The pseudo-element belongs to the label's own box, so a click anywhere in the row lands on the label and toggles the input. `cursor: pointer` moves to the root for the same reason -- the affordance should cover exactly what is clickable.
This commit is contained in:
@@ -11,19 +11,29 @@ import type { FilterBodyProps } from "./TextBody";
|
||||
const SEARCH_THRESHOLD = 8;
|
||||
|
||||
/**
|
||||
* Stretches the Checkbox/Radio's native <label> across the full popover
|
||||
* width and pads it, so the clickable/tappable area is the whole row —
|
||||
* not just the ~14px input square — plus a hover cue. `body`/`labelWrapper`
|
||||
* are Mantine's part names for this; `cursor: pointer` on the row (not just
|
||||
* the input) makes the affordance visible before you even click.
|
||||
* Whole-row hit target. The only element that toggles a Mantine Checkbox /
|
||||
* Radio is its native <label>, and that label wraps its own text and nothing
|
||||
* else — the row's padding and the gutter beside the input square lie
|
||||
* OUTSIDE it. Styling those on `root` therefore bought a hover cue over an
|
||||
* area that swallowed the click.
|
||||
*
|
||||
* The fix is a `::before` stretched over the (relatively positioned) root:
|
||||
* that pseudo-element is part of the label's own box, so a click anywhere in
|
||||
* the row hits the label and toggles the input. `cursor: pointer` goes on the
|
||||
* root for the same reason — the affordance must cover what is clickable.
|
||||
*/
|
||||
const ROW_STYLES = {
|
||||
root: { padding: "10px 10px", borderRadius: 6 },
|
||||
root: { position: "relative" as const, padding: "10px 10px", borderRadius: 6, cursor: "pointer" },
|
||||
body: { alignItems: "center" as const },
|
||||
labelWrapper: { flex: 1 },
|
||||
label: { cursor: "pointer", paddingLeft: 8 },
|
||||
};
|
||||
|
||||
const ROW_CLASSES = {
|
||||
root: "hover:bg-gray-100 transition-colors",
|
||||
label: "before:absolute before:inset-0 before:content-['']",
|
||||
};
|
||||
|
||||
function OptionLabel({ label, count }: { label: string; count?: number }) {
|
||||
return (
|
||||
<Group justify="space-between" wrap="nowrap" gap="sm">
|
||||
@@ -96,7 +106,7 @@ export function EnumBody({ def, value, onChange, onClose }: FilterBodyProps<Enum
|
||||
// just the tiny checkbox square) toggles the option too.
|
||||
label={<OptionLabel label={o.label} count={def.counts?.[o.value]} />}
|
||||
styles={ROW_STYLES}
|
||||
classNames={{ root: "hover:bg-gray-100 transition-colors" }}
|
||||
classNames={ROW_CLASSES}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
@@ -115,7 +125,7 @@ export function EnumBody({ def, value, onChange, onClose }: FilterBodyProps<Enum
|
||||
size="sm"
|
||||
label={<OptionLabel label={o.label} count={def.counts?.[o.value]} />}
|
||||
styles={ROW_STYLES}
|
||||
classNames={{ root: "hover:bg-gray-100 transition-colors" }}
|
||||
classNames={ROW_CLASSES}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user