Skip to content

Commit

Permalink
feat: Add compact checkbox option (#3651)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianjon3s authored Sep 20, 2024
1 parent 3549e61 commit d9f72b9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ const Search: React.FC = () => {
});

const debouncedSearch = useMemo(
() => debounce((pattern: string) => {
console.debug("Search term: ", pattern)
return search(pattern);
}, DEBOUNCE_MS),
[search]
() =>
debounce((pattern: string) => {
console.debug("Search term: ", pattern);
return search(pattern);
}, DEBOUNCE_MS),
[search],
);

return (
Expand Down Expand Up @@ -77,7 +78,8 @@ const Search: React.FC = () => {
id={"search-data-field-facet"}
checked
inputProps={{ disabled: true }}
onChange={() => { }}
onChange={() => {}}
variant="compact"
/>
<Box pt={3}>
{formik.values.pattern && (
Expand Down
92 changes: 64 additions & 28 deletions editor.planx.uk/src/ui/shared/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,79 @@ import React from "react";
import { borderedFocusStyle } from "theme";

const Root = styled(Box, {
shouldForwardProp: (prop) => !["disabled"].includes(prop.toString()),
})<BoxProps & { disabled?: boolean }>(({ theme, disabled }) => ({
display: "inline-flex",
flexShrink: 0,
position: "relative",
width: 40,
height: 40,
borderColor: theme.palette.text.primary,
border: "2px solid",
backgroundColor: theme.palette.common.white,
"&:focus-within": borderedFocusStyle,
...(disabled && {
border: `2px solid ${theme.palette.grey[400]}`,
backgroundColor: theme.palette.grey[400],
shouldForwardProp: (prop) =>
!["disabled", "variant"].includes(prop.toString()),
})<BoxProps & { disabled?: boolean; variant?: "default" | "compact" }>(
({ theme, disabled, variant }) => ({
display: "inline-flex",
flexShrink: 0,
position: "relative",
width: 40,
height: 40,
borderColor: theme.palette.text.primary,
border: "2px solid",
backgroundColor: theme.palette.common.white,
"&:focus-within": borderedFocusStyle,
...(disabled && {
border: `2px solid ${theme.palette.grey[400]}`,
backgroundColor: theme.palette.grey[400],
}),
...(variant === "compact" && {
width: 24,
height: 24,
}),
}),
}));
);

const Input = styled("input")(() => ({
opacity: 0,
width: 24,
height: 24,
cursor: "pointer",
}));
const Input = styled("input")<{ variant?: "default" | "compact" }>(
({ variant }) => ({
opacity: 0,
width: 24,
height: 24,
cursor: "pointer",
...(variant === "compact" && {
width: 16,
height: 16,
}),
}),
);

interface IconProps extends React.HTMLAttributes<HTMLSpanElement> {
checked: boolean;
disabled?: boolean;
variant?: "default" | "compact";
}

const Icon = styled("span", {
shouldForwardProp: (prop) =>
!["checked", "disabled"].includes(prop.toString()),
})<IconProps>(({ theme, checked, disabled }) => ({
!["checked", "disabled", "variant"].includes(prop.toString()),
})<IconProps>(({ theme, checked, disabled, variant }) => ({
display: checked ? "block" : "none",
content: "''",
position: "absolute",
height: 24,
width: 12,
borderColor: theme.palette.text.primary,
borderBottom: "5px solid",
borderRight: "5px solid",
left: "50%",
top: "42%",
transform: "translate(-50%, -50%) rotate(45deg)",
cursor: "pointer",
...(variant === "compact" && {
height: 12,
width: 7,
borderBottom: "3px solid",
borderRight: "3px solid",
top: "44%",
}),
...(disabled && {
borderBottom: `5px solid white`,
borderRight: `5px solid white`,
borderBottom: "5px solid",
borderRight: "5px solid",
borderColor: theme.palette.common.white,
...(variant === "compact" && {
borderBottom: "3px solid",
borderRight: "3px solid",
}),
}),
}));

Expand All @@ -60,29 +85,40 @@ export interface Props {
checked: boolean;
onChange?: (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
variant?: "default" | "compact";
}

export default function Checkbox({
id,
checked,
onChange,
inputProps,
variant = "default",
}: Props): FCReturn {
const handleChange = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
e.preventDefault();
onChange && onChange();
};

return (
<Root onClick={handleChange} disabled={inputProps?.disabled}>
<Root
onClick={handleChange}
disabled={inputProps?.disabled}
variant={variant}
>
<Input
defaultChecked={checked}
type="checkbox"
id={id}
data-testid={id}
{...inputProps}
variant={variant}
/>
<Icon
checked={checked}
disabled={inputProps?.disabled}
variant={variant}
/>
<Icon checked={checked} disabled={inputProps?.disabled} />
</Root>
);
}
3 changes: 3 additions & 0 deletions editor.planx.uk/src/ui/shared/ChecklistItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface Props {
checked: boolean;
onChange: (event?: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
variant?: "default" | "compact";
}

export default function ChecklistItem({
Expand All @@ -35,6 +36,7 @@ export default function ChecklistItem({
checked,
id,
inputProps,
variant,
}: Props): FCReturn {
return (
<Root>
Expand All @@ -43,6 +45,7 @@ export default function ChecklistItem({
id={id}
onChange={onChange}
inputProps={inputProps}
variant={variant}
/>
<Label variant="body1" className="label" component={"label"} htmlFor={id}>
{label}
Expand Down

0 comments on commit d9f72b9

Please sign in to comment.