-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sds, css-utils): Checkbox 컴포넌트 추가 (#128)
* feat: check 아이콘 추가 * feat: getCssVar * fix: sds 의존성 정리 * feat: Checkbox
- Loading branch information
1 parent
b322842
commit 86d43d4
Showing
10 changed files
with
174 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export const getCssVar = (cssVariable: string, initial?: unknown) => { | ||
return initial == null ? `var(${cssVariable})` : `var(${cssVariable}, ${initial})`; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export { getBorder } from './getBorder'; | ||
export { getCssVar } from './getCssVar'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { useId } from '@sambad/react-utils'; | ||
import { CSSProperties, forwardRef, InputHTMLAttributes, ReactNode } from 'react'; | ||
|
||
import { useControllableState } from '@sds/hooks'; | ||
import { colors } from '@sds/theme'; | ||
import { composeEventHandlers } from '@sds/utils'; | ||
|
||
import { Icon } from '../Icon'; | ||
import { Txt } from '../Typography'; | ||
|
||
import { checkboxRootCss, checkedVariants, iconCss, indicatorCss, inputCss, labelCss } from './styles'; | ||
|
||
export interface CheckboxProps extends InputHTMLAttributes<HTMLInputElement> { | ||
label?: ReactNode; | ||
onCheckedChange?: (checked: boolean) => void; | ||
} | ||
|
||
export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>((props, ref) => { | ||
const { label, checked: checkedFromProps, defaultChecked, onCheckedChange, disabled, ...restProps } = props; | ||
|
||
const id = useId(); | ||
|
||
const [checked = false, setChecked] = useControllableState({ | ||
prop: checkedFromProps, | ||
defaultProp: defaultChecked, | ||
onChange: onCheckedChange, | ||
}); | ||
|
||
const rootStyle = { | ||
...checkedVariants[checked ? 'checked' : 'default'], | ||
} as CSSProperties; | ||
|
||
return ( | ||
<div css={checkboxRootCss} style={rootStyle}> | ||
<input | ||
ref={ref} | ||
id={id} | ||
type="checkbox" | ||
role="checkbox" | ||
checked={checked} | ||
disabled={disabled} | ||
onClick={composeEventHandlers(props.onClick, () => { | ||
setChecked((prev) => !prev); | ||
})} | ||
css={inputCss} | ||
aria-checked={checked} | ||
aria-disabled={disabled} | ||
tabIndex={0} | ||
{...restProps} | ||
/> | ||
<span css={indicatorCss} /> | ||
{checked && <Icon css={iconCss} name="check" size={12} color={colors.white} />} | ||
{label != null && ( | ||
<Txt typography="subtitle1" css={labelCss}> | ||
<label htmlFor={id}>{label}</label> | ||
</Txt> | ||
)} | ||
</div> | ||
); | ||
}); | ||
|
||
Checkbox.displayName = 'Checkbox'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { Checkbox } from './Checkbox'; | ||
export type { CheckboxProps } from './Checkbox'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { css } from '@emotion/react'; | ||
import { getCssVar } from '@sambad/css-utils'; | ||
import { CSSProperties } from 'react'; | ||
|
||
import { colors, size } from '@sds/theme'; | ||
|
||
const inputBackgroundColorVar = '--sambad-checkbox-input-background-color'; | ||
const inputBoxShadowVar = '--sambad-checkbox-input-box-shadow'; | ||
|
||
interface CheckedVariants { | ||
[inputBackgroundColorVar]: CSSProperties['backgroundColor']; | ||
[inputBoxShadowVar]: CSSProperties['boxShadow']; | ||
} | ||
|
||
export const checkedVariants: Record<'checked' | 'default', CheckedVariants> = { | ||
default: { | ||
[inputBackgroundColorVar]: 'transparent', | ||
[inputBoxShadowVar]: `inset 0 0 0 1.5px ${colors.grey500}`, | ||
}, | ||
checked: { | ||
[inputBackgroundColorVar]: colors.black, | ||
[inputBoxShadowVar]: 'none', | ||
}, | ||
}; | ||
|
||
export const inputCss = css({ | ||
// NOTE: hidden 요소로 기능을 담당하고, 스타일은 indicator에서 담당하므로 width, height를 동일하게 | ||
width: '18px', | ||
height: '18px', | ||
opacity: 0, | ||
}); | ||
|
||
export const indicatorCss = css({ | ||
width: '18px', | ||
height: '18px', | ||
boxShadow: getCssVar(inputBoxShadowVar), | ||
backgroundColor: getCssVar(inputBackgroundColorVar), | ||
borderRadius: '3px', | ||
pointerEvents: 'none', | ||
position: 'absolute', | ||
transition: 'background-color 0.1s ease-in-out', | ||
}); | ||
|
||
export const labelCss = css({ | ||
marginLeft: size['6xs'], | ||
}); | ||
|
||
export const checkboxRootCss = css({ | ||
display: 'inline-flex', | ||
alignItems: 'center', | ||
position: 'relative', | ||
}); | ||
|
||
export const iconCss = css({ | ||
position: 'absolute', | ||
pointerEvents: 'none', | ||
left: '3px', | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { IconAssetProps } from '../types'; | ||
|
||
export const CheckIcon = (props: IconAssetProps) => { | ||
const { color, size } = props; | ||
|
||
return ( | ||
<svg width={size} height={size} viewBox="0 0 12 10" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
<path | ||
id="Vector 5492 (Stroke)" | ||
fillRule="evenodd" | ||
clipRule="evenodd" | ||
d="M11.7193 1.06225C12.0496 1.33661 12.0949 1.8268 11.8206 2.1571L6.74016 8.27332C5.84693 9.34866 4.21491 9.40215 3.25319 8.38762L0.213232 5.18074C-0.0821752 4.86911 -0.0690255 4.37701 0.242603 4.0816C0.554231 3.78619 1.04633 3.79934 1.34174 4.11097L4.38169 7.31785C4.70227 7.65603 5.24628 7.6382 5.54402 7.27975L10.6244 1.16353C10.8988 0.833228 11.389 0.787881 11.7193 1.06225Z" | ||
fill={color} | ||
/> | ||
</svg> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.