Skip to content

Commit ae28981

Browse files
authored
Merge pull request #429 from hyu-dev/main
Enhance components Checkbox
2 parents 8beed20 + 73b44b6 commit ae28981

File tree

6 files changed

+138
-88
lines changed

6 files changed

+138
-88
lines changed

.changeset/nine-bees-happen.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@devup-ui/components': patch
3+
---
4+
5+
Enhance Checkbox component logic

packages/components/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@
4343
"types": "./dist/index.d.ts",
4444
"dependencies": {
4545
"@devup-ui/react": "workspace:*",
46-
"csstype": "^3.1",
47-
"react": "^19.2",
46+
"csstype": "^3.1.3",
47+
"react": "^19.1.1",
48+
"react-dom": "^19.1.1",
4849
"clsx": "^2.1"
4950
},
5051
"devDependencies": {

packages/components/src/components/Checkbox/__tests__/__snapshots__/index.browser.test.tsx.snap

Lines changed: 66 additions & 52 deletions
Large diffs are not rendered by default.

packages/components/src/components/Checkbox/__tests__/index.browser.test.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ describe('Checkbox', () => {
325325
<Checkbox colors={customColors}>Test Checkbox</Checkbox>,
326326
)
327327

328-
const input = container.querySelector('input')
328+
const input = container.querySelector('span')
329329
expect(input).toHaveStyle({
330330
'--text': '#text-custom',
331331
})
@@ -352,10 +352,12 @@ describe('Checkbox', () => {
352352
}
353353

354354
const { container } = render(
355-
<Checkbox colors={customColors}>Test Checkbox</Checkbox>,
355+
<Checkbox checked colors={customColors}>
356+
Test Checkbox
357+
</Checkbox>,
356358
)
357359

358-
const input = container.querySelector('input')
360+
const input = container.querySelector('label svg')
359361
expect(input).toHaveStyle({
360362
'--checkIcon': '#checkIcon-custom',
361363
})
@@ -378,9 +380,7 @@ describe('Checkbox', () => {
378380
expect(input).toHaveStyle({
379381
'--primary': '#primary-custom',
380382
'--border': '#border-custom',
381-
'--text': '#text-custom',
382383
'--inputBg': '#inputBg-custom',
383-
'--checkIcon': '#checkIcon-custom',
384384
})
385385
})
386386

packages/components/src/components/Checkbox/index.tsx

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
'use client'
2+
13
import { Box, css, Flex, Input, Text } from '@devup-ui/react'
2-
import { ComponentProps, useId } from 'react'
4+
import { ComponentProps, useId, useState } from 'react'
35

46
import { CheckIcon } from './CheckIcon'
57

@@ -20,22 +22,42 @@ export function Checkbox({
2022
children,
2123
disabled,
2224
checked,
25+
defaultChecked = false,
2326
colors,
2427
onChange,
2528
...props
2629
}: CheckboxProps) {
2730
const generateId = useId()
31+
const [innerChecked, setInnerChecked] = useState(defaultChecked)
32+
const finalChecked = checked ?? innerChecked
33+
34+
const handleChange = (value: boolean) => {
35+
setInnerChecked(value)
36+
onChange?.(value)
37+
}
38+
2839
return (
2940
<Flex alignItems="center" gap="8px">
30-
<Box h="18px" pos="relative" w="fit-content">
41+
<label
42+
className={css({
43+
position: 'relative',
44+
display: 'flex',
45+
alignItems: 'center',
46+
justifyContent: 'center',
47+
width: '16px',
48+
height: '16px',
49+
cursor: disabled ? 'not-allowed' : 'pointer',
50+
})}
51+
htmlFor={generateId}
52+
>
3153
<Input
3254
_active={
3355
!disabled && {
3456
bg: 'light-dark(color-mix(in srgb, var(--primary, #6159D4) 20%, #FFF 80%), color-mix(in srgb, var(--primary, #6670F9) 30%, #000 70%))',
3557
}
3658
}
3759
_checked={{
38-
bg: 'light-dark(var(--primary, #6159D4), var(--primary, #6670F9))',
60+
bg: 'var(--primary, light-dark(#6159D4, #6670F9))',
3961
border: 'none',
4062
_hover: !disabled && {
4163
bg: 'light-dark(color-mix(in srgb, var(--primary, #6159D4) 100%, #000 15%), color-mix(in srgb, var(--primary, #6670F9) 100%, #FFF 15%))',
@@ -50,55 +72,57 @@ export function Checkbox({
5072
_hover={
5173
!disabled && {
5274
bg: 'light-dark(color-mix(in srgb, var(--primary, #6159D4) 10%, #FFF 90%), color-mix(in srgb, var(--primary, #6670F9) 20%, #000 80%))',
53-
border:
54-
'1px solid light-dark(var(--primary, #6159D4), var(--primary, #6670F9))',
75+
border: '1px solid var(--primary, light-dark(#6159D4, #6670F9))',
5576
}
5677
}
57-
accentColor="light-dark(var(--primary, #6159D4), var(--primary, #6670F9))"
78+
accentColor="var(--primary, light-dark(#6159D4, #6670F9))"
5879
appearance="none"
59-
bg="light-dark(#FFF, var(--inputBg, #2E2E2E))"
60-
border="1px solid light-dark(var(--border, #E0E0E0), var(--border, #333333))"
80+
bg="var(--inputBg, light-dark(#FFF, #2E2E2E))"
81+
border="1px solid var(--border, light-dark(#E0E0E0, #333333))"
6182
borderRadius="2px"
62-
boxSize="16px"
63-
checked={checked}
83+
checked={finalChecked}
6484
cursor={disabled ? 'not-allowed' : 'pointer'}
6585
disabled={disabled}
86+
display="block"
87+
height="100%"
6688
id={generateId}
89+
left={0}
6790
m="0"
6891
onChange={
69-
disabled || !onChange
70-
? undefined
71-
: (e) => onChange(e.target.checked)
92+
disabled ? undefined : (e) => handleChange(e.target.checked)
7293
}
94+
opacity={1}
95+
pointerEvents="none"
96+
pos="absolute"
7397
styleOrder={1}
7498
styleVars={{
7599
primary: colors?.primary,
76100
border: colors?.border,
77-
text: colors?.text,
78101
inputBg: colors?.inputBg,
79-
checkIcon: colors?.checkIcon,
80102
}}
103+
top={0}
81104
type="checkbox"
105+
width="100%"
106+
zIndex={0}
82107
{...props}
83108
/>
84-
{checked && (
109+
{finalChecked && (
85110
<Box
86111
as={CheckIcon}
112+
opacity="1"
113+
pointerEvents="none"
87114
props={{
88115
color: disabled
89-
? 'light-dark(#D6D7DE, #373737)'
116+
? 'light-dark(#D6D7DE, #47474A)'
90117
: 'var(--checkIcon, #FFF)',
91-
className: css({
92-
left: '50%',
93-
pointerEvents: 'none',
94-
pos: 'absolute',
95-
top: '60%',
96-
transform: 'translate(-50%, -50%)',
97-
}),
98118
}}
119+
styleVars={{
120+
checkIcon: colors?.checkIcon,
121+
}}
122+
zIndex="1"
99123
/>
100124
)}
101-
</Box>
125+
</label>
102126

103127
<label
104128
className={css({
@@ -110,10 +134,13 @@ export function Checkbox({
110134
<Text
111135
color={
112136
disabled
113-
? 'light-dark(#D6D7DE, #373737)'
114-
: 'light-dark(var(--text, #2F2F2F), var(--text, #EDEDED))'
137+
? 'light-dark(#D6D7DE, #6F6E6E)'
138+
: 'var(--text, light-dark(#2F2F2F, #EDEDED))'
115139
}
116140
fontSize="14px"
141+
styleVars={{
142+
text: colors?.text,
143+
}}
117144
userSelect="none"
118145
>
119146
{children}

pnpm-lock.yaml

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)