Skip to content

Commit

Permalink
fix checkbox and switch
Browse files Browse the repository at this point in the history
  • Loading branch information
vassbence committed Nov 14, 2024
1 parent be01745 commit 6d7b9bc
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 161 deletions.
16 changes: 2 additions & 14 deletions src/components/CheckboxInput/CheckboxInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,7 @@ export const Disabled = () => {
return <CheckboxInput value={value} onChange={setValue} disabled />
}

export const SmallDefault = () => {
export const WithLabel = () => {
const [value, setValue] = useState(false)
return <CheckboxInput size="small" value={value} onChange={setValue} />
}

export const SmallError = () => {
const [value, setValue] = useState(true)
return <CheckboxInput size="small" error value={value} onChange={setValue} />
}

export const SmallDisabled = () => {
const [value, setValue] = useState(true)
return (
<CheckboxInput size="small" value={value} onChange={setValue} disabled />
)
return <CheckboxInput value={value} onChange={setValue} error label="Label" />
}
155 changes: 83 additions & 72 deletions src/components/CheckboxInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,98 +2,109 @@ import { radius } from '../../utils/radius.js'
import { Icon } from '../Icon/index.js'
import { colors } from '../../utils/colors.js'
import { styled } from 'inlines'
import { Text } from '../Text/index.js'

type CheckboxInputProps = {
value?: boolean
onChange: (value: boolean) => void
disabled?: boolean
error?: boolean
size?: 'regular' | 'small'
label?: string
}

function CheckboxInput({
value,
onChange,
disabled,
error,
size = 'regular',
label,
}: CheckboxInputProps) {
return (
<styled.label
data-disabled={disabled ? disabled : undefined}
data-checked={value ? value : undefined}
data-error={error ? value : undefined}
style={{
position: 'relative',
overflow: 'hidden',
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
width: size === 'small' ? 16 : 20,
height: size === 'small' ? 16 : 20,
borderRadius: radius[4],
border: `1px solid ${colors.neutral20Adjusted}`,
background: 'transparent',
cursor: 'pointer',
outline: 'none',
color: colors.neutralInverted100,
'&[data-checked]': {
border: `1px solid ${colors.neutral100}`,
background: colors.neutral100,
},
'&:has(:focus-visible):not([data-disabled])': {
outline: `4px solid ${colors.neutral20Adjusted}`,
},
'&[data-error]': {
border: `1px solid ${colors.red100}`,
},
'&[data-error][data-checked]': {
background: colors.red100,
},
'&[data-error]:has(:focus-visible):not([data-disabled])': {
outline: `4px solid ${colors.red60}`,
},
'&[data-disabled]': {
cursor: 'not-allowed',
border: `1px solid transparent`,
background: colors.neutral20,
},
}}
>
{value && (
<span
<label style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
<styled.div
data-disabled={disabled ? disabled : undefined}
data-checked={value ? value : undefined}
data-error={error ? value : undefined}
style={{
position: 'relative',
overflow: 'hidden',
display: 'inline-flex',
justifyContent: 'center',
alignItems: 'center',
width: 20,
height: 20,
borderRadius: radius[4],
border: `1px solid ${colors.neutral20Adjusted}`,
background: 'transparent',
cursor: 'pointer',
outline: 'none',
color: colors.neutralInverted100,
'&[data-checked]': {
border: `1px solid ${colors.neutral100}`,
background: colors.neutral100,
},
'&:has(:focus-visible):not([data-disabled])': {
outline: `4px solid ${colors.neutral20Adjusted}`,
},
'&[data-error]': {
border: `1px solid ${colors.red100}`,
},
'&[data-error][data-checked]': {
background: colors.red100,
},
'&[data-error]:has(:focus-visible):not([data-disabled])': {
outline: `4px solid ${colors.red60}`,
},
'&[data-disabled]': {
cursor: 'not-allowed',
border: `1px solid transparent`,
background: colors.neutral20,
},
}}
>
{value && (
<span
style={{
position: 'absolute',
pointerEvents: 'none',
left: -3,
top: -3,
}}
>
<Icon variant="checkmark" />
</span>
)}
<input
style={{
position: 'absolute',
pointerEvents: 'none',
left: size === 'small' ? -5 : -3,
top: size === 'small' ? -5 : -3,
width: 1,
height: 1,
padding: 0,
margin: -1,
overflow: 'hidden',
clip: 'rect(0, 0, 0, 0)',
whiteSpace: 'nowrap',
borderWidth: 0,
}}
type="checkbox"
checked={value ?? false}
onChange={() => {
if (disabled) return

onChange(!value)
}}
disabled={disabled}
/>
</styled.div>
{label && (
<Text
variant="display-regular"
color={value && !disabled ? 'neutral100' : 'neutral60'}
>
<Icon variant={size === 'small' ? 'checkmark-small' : 'checkmark'} />
</span>
{label}
</Text>
)}
<input
style={{
position: 'absolute',
width: 1,
height: 1,
padding: 0,
margin: -1,
overflow: 'hidden',
clip: 'rect(0, 0, 0, 0)',
whiteSpace: 'nowrap',
borderWidth: 0,
}}
type="checkbox"
checked={value ?? false}
onChange={() => {
if (disabled) return

onChange(!value)
}}
disabled={disabled}
/>
</styled.label>
</label>
)
}

Expand Down
2 changes: 0 additions & 2 deletions src/components/List/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ function List({
>
{onSelectChange && (
<CheckboxInput
size="small"
value={data.length && data.every((e) => select?.includes(e.id))}
onChange={() => {
if (!select) {
Expand Down Expand Up @@ -153,7 +152,6 @@ function List({
}}
>
<CheckboxInput
size="small"
value={select?.includes(item.id)}
onChange={() => {
if (!select) {
Expand Down
16 changes: 11 additions & 5 deletions src/components/SwitchInput/SwitchInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ export const Default = () => {
return <SwitchInput value={value} onChange={setValue} />
}

export const Error = () => {
export const Disabled = () => {
const [value, setValue] = useState(true)
return <SwitchInput error value={value} onChange={setValue} />
return <SwitchInput value={value} onChange={setValue} disabled />
}

export const Disabled = () => {
const [value, setValue] = useState(false)
return <SwitchInput value={value} onChange={setValue} disabled />
export const WithLabel = () => {
const [value, setValue] = useState(true)
return (
<SwitchInput
value={value}
onChange={setValue}
label={value ? 'Enabled' : 'Disabled'}
/>
)
}
Loading

0 comments on commit 6d7b9bc

Please sign in to comment.