Skip to content

Commit

Permalink
feat(checkbox): add checkbox
Browse files Browse the repository at this point in the history
  • Loading branch information
JimmyBenKlieve committed Aug 13, 2023
1 parent 9a1f481 commit d9e6eb6
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 1 deletion.
65 changes: 64 additions & 1 deletion docs/src/app/module/checkbox/page.mdx
Original file line number Diff line number Diff line change
@@ -1 +1,64 @@
# Checkbox 复选框
# Checkbox 复选框

## 未选定和选定状态

```tsx
import { Checkbox } from '@yike-design/react';

export default () => {
return (
<div>
<Checkbox>选项 1</Checkbox>
<Checkbox checked>选项 2</Checkbox>
</div>
);
};
```

## 特殊的半选状态

```tsx
import { Checkbox } from '@yike-design/react';

export default () => {
return (
<div>
<Checkbox indeterminate>半选</Checkbox>
</div>
);
};
```

## 已禁用

```tsx
import { Checkbox } from '@yike-design/react';

export default () => {
return (
<div>
<Checkbox disabled>未选</Checkbox>
<Checkbox
checked
disabled
>
已选
</Checkbox>
<Checkbox
indeterminate
disabled
>
半选
</Checkbox>
</div>
);
};
```

## API

| 属性 | 类型 | 默认值 | 说明 |
| --------------- | ------------------------------ | ------- | ------------------------ |
| `checked` | `boolean` | `false` | 设置是否勾选的状态 |
| `indeterminate` | `boolean` | `false` | 设置是否为半选状态 |
| `onChange` | `(isChecked: boolean) => void` | - | 勾选状态改变时的回调函数 |
62 changes: 62 additions & 0 deletions packages/yike-design/src/components/Checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use client';

import React from 'react';

import './style/Checkbox.scss';

export interface CheckboxProps {
checked?: boolean;
indeterminate?: boolean;

onChange: (isChecked: boolean) => void;
}

const Checkbox: React.FC<
CheckboxProps & Omit<React.InputHTMLAttributes<HTMLInputElement>, keyof CheckboxProps>
> = props => {
const {
children,
checked = false,
indeterminate = false,
onChange,

// rest
...restProps
} = props;

const inputRef = React.useRef<HTMLInputElement>(null);

const handleChange = React.useCallback<React.ChangeEventHandler<HTMLInputElement>>(
evt => {
const { checked } = evt.target;

if (typeof onChange === 'function') {
onChange(checked);
}
},
[onChange]
);

React.useLayoutEffect(() => {
if (inputRef.current) {
inputRef.current.indeterminate = indeterminate;
}
}, [indeterminate]);

return (
<div className="yike-checkbox">
<label>
<input
ref={inputRef}
{...restProps}
type="checkbox"
checked={checked}
onChange={handleChange}
/>
<span className="yike-checkbox_content">{children}</span>
</label>
</div>
);
};

export default Checkbox;
3 changes: 3 additions & 0 deletions packages/yike-design/src/components/Checkbox/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Checkbox from './Checkbox';

export { Checkbox };
103 changes: 103 additions & 0 deletions packages/yike-design/src/components/Checkbox/style/Checkbox.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
@use 'sass:color';
@use '../../../styles/tokens/index' as base;

.#{base.$prefix}-checkbox {
display: inline-flex;
margin-right: 1rem;

> label {
position: relative;

> input[type='checkbox'] {
position: absolute;
visibility: hidden;
opacity: 0;

&:checked {
+ .#{base.$prefix}-checkbox_content {
&::before {
background-color: base.$color-primary;
border-color: base.$color-primary;
}

&::after {
opacity: 1;
}
}
}

&:indeterminate {
+ .#{base.$prefix}-checkbox_content {
&::before {
background-color: base.$color-primary;
border-color: base.$color-primary;
}

&::after {
top: 50%;
height: 0;
border-left: none;
opacity: 1;
transform: translate(-50%);
}
}
}

&:disabled {
+ .#{base.$prefix}-checkbox_content {
&::before {
cursor: auto;
background-color: #f3f3f4;
border-color: #e8e9eb;
}

&::after {
border-color: #000;
}
}
}
}

.#{base.$prefix}-checkbox_content {
padding-left: 1.5em;

&::before {
position: absolute;
top: 50%;
left: 0;
display: block;
width: 1em;
height: 1em;
line-height: 1em;
cursor: pointer;
content: ' ';
border: 1px solid color.mix(#1e2025, #fff, 18%);
border-radius: 4px;
transition: all base.$motion-duration-short3 base.$motion-easing-standard;
transform: translateY(-50%);
}

&::after {
position: absolute;
top: calc(50% - 1px);
left: 0.5em;
width: 0.5em;
height: 0.25em;
pointer-events: none;
content: ' ';
border-bottom: 1px solid #fff;
border-left: 1px solid #fff;
opacity: 0;
transform: translate(-50%, -50%) rotate(-45deg);
}
}

&:hover {
.#{base.$prefix}-checkbox_content {
&::before {
border-color: base.$color-primary;
}
}
}
}
}
1 change: 1 addition & 0 deletions packages/yike-design/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './components/Button';
export * from './components/Space';
export * from './components/Checkbox';

0 comments on commit d9e6eb6

Please sign in to comment.