Skip to content

Commit

Permalink
Checkbox improvements (#1157)
Browse files Browse the repository at this point in the history
- Added Aux Label prop
- Fixed minor CSS issues

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
  • Loading branch information
bexsoft authored Dec 31, 2024
1 parent d49efab commit a194db2
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 69 deletions.
10 changes: 10 additions & 0 deletions src/components/Checkbox/Checkbox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,13 @@ LabelNoMinWidth.args = {
disabled: true,
noLabelMinWidth: true,
};

export const AuxLabel = Template.bind({});
AuxLabel.args = {
label: "Do you want to continue?",
id: "checkbox",
onClick: () => {
console.log("click");
},
auxLabel: "Yes",
};
113 changes: 61 additions & 52 deletions src/components/Checkbox/Checkbox.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,69 +14,78 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

import { Theme } from "@emotion/react";
import { css, Theme } from "@emotion/react";

export const checkboxStyles = (theme: Theme) => ({
position: "relative",
"& input": {
display: "none",
},
"& .checkbox": {
export const checkboxStyles = (theme: Theme) =>
css({
position: "relative",
display: "block",
width: 16,
height: 16,
borderRadius: 4,
border: `1px solid ${theme.colors["Color/Neutral/Border/colorBorderSubtle"]}`,
backgroundColor: theme.colors["Color/Neutral/Bg/colorBgFields"],
boxSizing: "border-box" as const,
"&:hover:not(:disabled)": {
borderColor: theme.colors["Color/Neutral/Border/colorBorderBold"],
},
"& .icon-overlay": {
"& input": {
display: "none",
},
},
"input:checked ~ .checkbox": {
borderColor: theme.colors["Color/Brand/Primary/colorPrimary"],
backgroundColor: theme.colors["Color/Brand/Primary/colorPrimary"],
overflow: "hidden",
"&:before": {
content: "' '",
position: "absolute",
"& .checkbox": {
position: "relative",
display: "block",
width: 16,
height: 16,
borderRadius: 4,
top: "50%",
left: "50%",
transform: "translateX(-50%) translateY(-50%)",
},
"& .icon-overlay": {
display: "block",
},
"&:hover": {
borderColor: theme.colors["Color/Brand/Primary/colorPrimaryHover"],
backgroundColor: theme.colors["Color/Brand/Primary/colorPrimaryHover"],
},
},
"input:disabled": {
"& ~ .checkbox": {
border: `1px solid ${theme.colors["Color/Neutral/Border/colorBorderSubtle"]}`,
backgroundColor: theme.colors["Color/Neutral/Bg/colorBgDisabled"],
backgroundColor: theme.colors["Color/Neutral/Bg/colorBgFields"],
boxSizing: "border-box" as const,
"&:hover:not(:disabled)": {
borderColor: theme.colors["Color/Neutral/Border/colorBorderBold"],
},
"& .icon-overlay": {
display: "none",
},
},
"input:checked ~ .checkbox": {
borderColor: theme.colors["Color/Brand/Primary/colorPrimary"],
backgroundColor: theme.colors["Color/Brand/Primary/colorPrimary"],
overflow: "hidden",
"&:before": {
content: "' '",
position: "absolute",
display: "block",
width: 16,
height: 16,
borderRadius: 4,
top: "50%",
left: "50%",
transform: "translateX(-50%) translateY(-50%)",
},
"& .icon-overlay": {
display: "block",
},
"&:hover": {
borderColor: theme.colors["Color/Neutral/Border/colorBorderSubtle"],
borderColor: theme.colors["Color/Brand/Primary/colorPrimaryHover"],
backgroundColor: theme.colors["Color/Brand/Primary/colorPrimaryHover"],
},
},
"input:disabled": {
"& ~ .checkbox": {
border: `1px solid ${theme.colors["Color/Neutral/Border/colorBorderSubtle"]}`,
backgroundColor: theme.colors["Color/Neutral/Bg/colorBgDisabled"],
cursor: "not-allowed",
"&:hover": {
borderColor: theme.colors["Color/Neutral/Border/colorBorderSubtle"],
backgroundColor: theme.colors["Color/Neutral/Bg/colorBgDisabled"],
},
},
},
},
"& .icon-overlay": {
color: theme.colors["Color/Neutral/Text/colorTextLightSolid"],
position: "absolute",
width: 14,
height: 14,
"&.disabled": {
color: theme.colors["Color/Neutral/Text/colorTextDisabled"],
"& .icon-overlay": {
color: theme.colors["Color/Neutral/Text/colorTextLightSolid"],
position: "absolute",
width: 14,
height: 14,
"&.disabled": {
color: theme.colors["Color/Neutral/Text/colorTextDisabled"],
},
},
},
});
});

export const checkContainer = (theme: Theme) =>
css({
display: "flex",
gap: theme.paddingSizes.size,
alignItems: "center",
});
1 change: 1 addition & 0 deletions src/components/Checkbox/Checkbox.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface CheckboxProps extends HTMLAttributes<HTMLInputElement> {
tooltip?: string;
overrideLabelClasses?: string;
noLabelMinWidth?: boolean;
auxLabel?: string;
sx?: OverrideTheme;
helper?: string;
}
41 changes: 24 additions & 17 deletions src/components/Checkbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import CircleHelpIcon from "../../icons/CircleHelpIcon";
import InputHelper from "../InputHelper";
import InputLabel from "../InputLabel";
import Tooltip from "../Tooltip";
import { checkboxStyles } from "./Checkbox.styles";
import { checkboxStyles, checkContainer } from "./Checkbox.styles";
import { CheckboxProps } from "./Checkbox.types";

const Checkbox: FC<
Expand All @@ -40,6 +40,7 @@ const Checkbox: FC<
helper,
disabled,
noLabelMinWidth,
auxLabel,
...props
}) => {
const theme = useTheme();
Expand All @@ -53,6 +54,7 @@ const Checkbox: FC<
}, [sx, theme]);

const checkboxTheme = checkboxStyles(theme);
const checkboxContainer = checkContainer(theme);

return (
<FieldContainer
Expand Down Expand Up @@ -90,22 +92,27 @@ const Checkbox: FC<
)}
</InputLabel>
)}
<label
css={[checkboxTheme, overrideThemes]}
onClick={(e) => e.stopPropagation()}
>
<input
type={"checkbox"}
id={id}
checked={checked}
disabled={disabled}
{...props}
/>
<span className={"checkbox"}>
<CheckIcon className={`${disabled ? "disabled" : ""} icon-overlay`} />
</span>
{helper !== undefined && <InputHelper>{helper}</InputHelper>}
</label>
<div css={checkboxContainer}>
<label
css={[checkboxTheme, overrideThemes]}
onClick={(e) => e.stopPropagation()}
>
<input
type={"checkbox"}
id={id}
checked={checked}
disabled={disabled}
{...props}
/>
<span className={"checkbox"}>
<CheckIcon
className={`${disabled ? "disabled" : ""} icon-overlay`}
/>
</span>
{helper !== undefined && <InputHelper>{helper}</InputHelper>}
</label>
{auxLabel && <InputLabel htmlFor={id}>{auxLabel}</InputLabel>}
</div>
</FieldContainer>
);
};
Expand Down

0 comments on commit a194db2

Please sign in to comment.