From 374cb3d720bdc23cc7c2fbe7a9ebe089f86f7be0 Mon Sep 17 00:00:00 2001 From: Kelly Phan Date: Thu, 19 Dec 2024 11:40:30 +0100 Subject: [PATCH] refactor: migrate checkbox component (#1926) * refactor: replace checkbox icons * refactor: tailwind migration --- src/components/form/Checkbox/Checkbox.tsx | 156 +++--------------- src/components/form/Checkbox/CheckboxIcon.tsx | 105 ++++++++++++ src/public/icons/forms/checkbox-checked.svg | 19 --- .../icons/forms/checkbox-indeterminate.svg | 10 -- src/public/icons/forms/checkbox.svg | 3 - 5 files changed, 129 insertions(+), 164 deletions(-) create mode 100644 src/components/form/Checkbox/CheckboxIcon.tsx delete mode 100644 src/public/icons/forms/checkbox-checked.svg delete mode 100644 src/public/icons/forms/checkbox-indeterminate.svg delete mode 100644 src/public/icons/forms/checkbox.svg diff --git a/src/components/form/Checkbox/Checkbox.tsx b/src/components/form/Checkbox/Checkbox.tsx index 24a3f20b5..765bd8ec4 100644 --- a/src/components/form/Checkbox/Checkbox.tsx +++ b/src/components/form/Checkbox/Checkbox.tsx @@ -1,13 +1,9 @@ -/* eslint-disable tailwindcss/no-custom-classname */ -import { cx } from 'class-variance-authority' -import { ChangeEvent, useRef, useState } from 'react' -import styled from 'styled-components' +import { ChangeEvent, useId, useRef, useState } from 'react' import { Typography } from '~/components/designSystem' -import CheckedIcon from '~/public/icons/forms/checkbox-checked.svg' -import IndeterminateIcon from '~/public/icons/forms/checkbox-indeterminate.svg' -import Icon from '~/public/icons/forms/checkbox.svg' -import { theme } from '~/styles' +import { tw } from '~/styles/utils' + +import { CheckboxIcon } from './CheckboxIcon' export interface CheckboxProps { canBeIndeterminate?: boolean @@ -32,23 +28,21 @@ export const Checkbox = ({ value, onChange, }: CheckboxProps) => { + const componentId = useId() + const inputRef = useRef(null) const [focused, setFocused] = useState(false) return ( - inputRef.current?.click()} + className={tw('flex flex-col', !disabled && 'cursor-pointer', className)} > -
- +
+
setFocused(true)} onBlur={() => setFocused(false)} + className="absolute m-0 size-0 p-0 opacity-0" /> - {!!value ? ( -
{typeof label === 'string' ? ( {label} @@ -103,102 +85,12 @@ export const Checkbox = ({ sublabel ))}
-
+ {!!error && ( - + {error} - + )} -
+ ) } - -const InputContainer = styled.div` - margin-right: ${theme.spacing(3)}; - display: inline-flex; - align-items: center; - - input { - opacity: 0; - position: absolute; - width: 0; - height: 0; - margin: 0; - padding: 0; - } -` - -const Container = styled.div` - display: flex; - flex-direction: column; -` - -const Main = styled.div` - display: flex; - align-items: flex-start; - vertical-align: middle; - margin-left: -11px; - margin-right: 16px; - margin-left: 0; - margin-right: 0; - cursor: pointer; - - > *:first-child { - padding-top: 4px; - } - - .MuiCheckbox-root { - margin-top: 0; - } - - > * { - line-height: 28px; - } - - &.checkbox--disabled { - cursor: initial; - - .checkbox-unchecked-icon rect { - stroke: ${theme.palette.grey[400]}; - } - } - - &:hover:not(.checkbox--disabled) { - .checkbox-unchecked-icon { - color: ${theme.palette.grey[200]}; - } - .checkbox-indeterminate-icon { - color: ${theme.palette.primary[700]}; - } - .checkbox-checked-icon { - color: ${theme.palette.primary[700]}; - } - } - - &:active:not(.checkbox--disabled) { - .checkbox-unchecked-icon { - color: ${theme.palette.grey[300]}; - } - .checkbox-indeterminate-icon { - color: ${theme.palette.primary[800]}; - } - .checkbox-checked-icon { - color: ${theme.palette.primary[800]}; - } - } - - &.checkbox--focused { - .checkbox-unchecked-icon, - .checkbox-indeterminate-icon, - .checkbox-checked-icon { - box-shadow: 0px 0px 0px 4px ${theme.palette.primary[200]}; - border-radius: 4px; - } - } -` - -const StyledTypography = styled(Typography)` - && { - margin-top: ${theme.spacing(1)}; - } -` diff --git a/src/components/form/Checkbox/CheckboxIcon.tsx b/src/components/form/Checkbox/CheckboxIcon.tsx new file mode 100644 index 000000000..7ec48a61e --- /dev/null +++ b/src/components/form/Checkbox/CheckboxIcon.tsx @@ -0,0 +1,105 @@ +import { FC } from 'react' + +import { tw } from '~/styles/utils' + +interface CheckboxCheckedIconProps { + disabled?: boolean + focused?: boolean +} + +const CheckboxCheckedIcon: FC = ({ disabled, focused }) => { + return ( + + ) +} + +const CheckboxUncheckedIcon: FC = ({ disabled, focused }) => { + return ( + + ) +} + +const CheckboxIndeterminateIcon: FC = ({ disabled, focused }) => { + return ( + + ) +} + +export const CheckboxIcon: FC< + { value?: boolean; canBeIndeterminate?: boolean } & CheckboxCheckedIconProps +> = ({ value, canBeIndeterminate, ...checkboxIconProps }) => { + return ( + <> + {value ? ( + + ) : value === undefined && canBeIndeterminate ? ( + + ) : ( + + )} + + ) +} diff --git a/src/public/icons/forms/checkbox-checked.svg b/src/public/icons/forms/checkbox-checked.svg deleted file mode 100644 index 65b00a5fe..000000000 --- a/src/public/icons/forms/checkbox-checked.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - diff --git a/src/public/icons/forms/checkbox-indeterminate.svg b/src/public/icons/forms/checkbox-indeterminate.svg deleted file mode 100644 index 4fb458f8d..000000000 --- a/src/public/icons/forms/checkbox-indeterminate.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/src/public/icons/forms/checkbox.svg b/src/public/icons/forms/checkbox.svg deleted file mode 100644 index 5b2e77b70..000000000 --- a/src/public/icons/forms/checkbox.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -