Skip to content

Commit 40034db

Browse files
author
Yang
committed
chore: checkbox mini
1 parent bc8e939 commit 40034db

11 files changed

Lines changed: 177 additions & 91 deletions

File tree

packages/mini-demo/order.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"input":{"AutoHeight":"6","Basic":"1","Clearable":"2","Disabled":"5","Native":"3","ReadOnly":"4","ShowLength":"7","Vertical":"8","Readonly":"4","Disable":0},"swipe-action":{"Basic":0}}
1+
{"input":{"AutoHeight":"6","Basic":"1","Clearable":"2","Disabled":"5","Native":"3","ReadOnly":"4","ShowLength":"7","Vertical":"8","Readonly":"4","Disable":0},"swipe-action":{"Basic":0},"checkbox":{"Controlled":0}}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React, { useState } from 'react';
2+
import { showModal } from '@tarojs/taro';
3+
import { Checkbox, List, Panel } from 'zarm/mini';
4+
5+
6+
const Demo = () => {
7+
const [checked, setChecked] = useState(false);
8+
9+
const onChange = (e) => {
10+
if (!e.target.checked) {
11+
showModal({
12+
content: '是否要取消选择',
13+
cancelText: '不取消',
14+
success: ({ confirm }) => {
15+
if (confirm) {
16+
setChecked(false);
17+
}
18+
},
19+
});
20+
return false;
21+
}
22+
setChecked(true);
23+
};
24+
25+
return (
26+
<Panel title="取消勾选前确认">
27+
<List>
28+
<List.Item>
29+
<Checkbox checked={checked} onChange={onChange}>
30+
取消勾选前确认
31+
</Checkbox>
32+
</List.Item>
33+
</List>
34+
</Panel>
35+
);
36+
};
37+
38+
export default Demo;
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
12
import * as React from 'react';
23
import Basic from './component/basic';
34
import Buttton from './component/buttton';
5+
import Controlled from './component/controlled';
46
import List from './component/list';
7+
58
import './index.scss';
69

710
export default () => {
811
return (
912
<>
1013
<Basic />
1114
<Buttton />
15+
<Controlled />
1216
<List />
1317
</>
14-
);
15-
};
18+
)
19+
}

packages/zarm/src/checkbox/Checkbox.mini.tsx

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { BaseEventOrig, Label, Switch, SwitchProps, View } from '@tarojs/compone
22
import { createBEM } from '@zarm-design/bem';
33
import { Minus as MinusIcon, Success as SuccessIcon } from '@zarm-design/icons';
44
import includes from 'lodash/includes';
5-
import React, { ReactNode, useContext, useEffect, useMemo, useState } from 'react';
5+
import React, { ReactNode, useContext, useMemo, } from 'react';
6+
import { useControllableEventValue } from '../utils/hooks';
67
import Button from '../button/index.mini';
78
import { ConfigContext } from '../config-provider';
89
import List from '../list';
@@ -19,19 +20,37 @@ export type CheckboxProps = BaseCheckboxProps &
1920
onChange?: (value: BaseEventOrig<SwitchProps.onChangeEventDetail>) => void;
2021
};
2122

22-
const getChecked = (props: CheckboxProps, defaultChecked?: boolean) => {
23-
return props.checked ?? props.defaultChecked ?? defaultChecked;
24-
};
23+
// const getChecked = (props: CheckboxProps, defaultChecked?: boolean) => {
24+
// return props.checked ?? props.defaultChecked ?? defaultChecked;
25+
// };
2526

2627
const Checkbox = (props: CheckboxProps) => {
27-
let [checked, setChecked] = useState(getChecked(props, false));
28+
// const defaultVal: Partial<{value: boolean, defaultValue: boolean}> = {};
29+
// if ('checked' in props) {
30+
// defaultVal.value = props.checked;
31+
// }
32+
// if ('defaultChecked' in props) {
33+
// defaultVal.defaultValue = props.defaultChecked;
34+
// }
35+
// let [checked, setChecked] = useControllableEventValue({
36+
// ...props,
37+
// ...defaultVal,
38+
// });
39+
40+
// console.log(checked);
41+
let [checked, setChecked] = useControllableEventValue(props, {
42+
valuePropName: 'checked',
43+
defaultValuePropName: 'defaultChecked'
44+
});
45+
checked = checked ?? false;
46+
2847
let { disabled } = props;
2948

3049
const groupContext = useContext(CheckboxGroupContext);
3150
if (groupContext && props.value !== undefined) {
3251
checked = includes(groupContext.value, props.value);
33-
setChecked = (changedChecked: boolean) => {
34-
if (changedChecked) {
52+
setChecked = (e: any) => {
53+
if (e.target.checked === true) {
3554
groupContext.check(props.value);
3655
} else {
3756
groupContext.uncheck(props.value);
@@ -84,22 +103,17 @@ const Checkbox = (props: CheckboxProps) => {
84103
className={bem('input')}
85104
disabled={disabled}
86105
checked={checked}
87-
onChange={(e: BaseEventOrig<SwitchProps.onChangeEventDetail>) => {
106+
onChange={() => {
88107
if (disabled) return;
89-
90-
if (!('checked' in props)) {
91-
setChecked(e.detail.value);
92-
}
93-
props.onChange?.(e);
108+
setChecked({
109+
target: {
110+
checked: !checked,
111+
}
112+
} as any);
113+
// props.onChange?.(e);
94114
}}
95115
/>
96116
);
97-
useEffect(() => {
98-
if (props.checked === undefined) return;
99-
if (props.checked === checked) return;
100-
101-
setChecked(getChecked({ checked: props.checked, defaultChecked: props.defaultChecked }, false));
102-
}, [props.checked, props.defaultChecked]);
103117

104118
if (groupContext?.type === 'button') {
105119
return (

packages/zarm/src/checkbox/Checkbox.tsx

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ import React, {
66
forwardRef,
77
ReactNode,
88
useContext,
9-
useEffect,
109
useImperativeHandle,
1110
useRef,
12-
useState,
1311
} from 'react';
1412
import Button from '../button';
1513
import { ConfigContext } from '../config-provider';
1614
import List from '../list';
1715
import type { HTMLProps } from '../utils/utilityTypes';
1816
import { CheckboxGroupContext } from './context';
1917
import type { BaseCheckboxProps, CheckboxCssVars } from './interface';
18+
import { useControllableEventValue } from '../utils/hooks';
19+
2020

2121
export type CheckboxProps = BaseCheckboxProps &
2222
HTMLProps<CheckboxCssVars> & {
@@ -25,10 +25,6 @@ export type CheckboxProps = BaseCheckboxProps &
2525
onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
2626
};
2727

28-
const getChecked = (props: CheckboxProps, defaultChecked?: boolean) => {
29-
return props.checked ?? props.defaultChecked ?? defaultChecked;
30-
};
31-
3228
export interface CheckboxRef {
3329
check: () => void;
3430
uncheck: () => void;
@@ -38,14 +34,18 @@ export interface CheckboxRef {
3834
const Checkbox = forwardRef<CheckboxRef, CheckboxProps>((props, ref) => {
3935
const inputRef = useRef<HTMLInputElement>(null);
4036

41-
let [checked, setChecked] = useState(getChecked(props, false));
37+
let [checked, setChecked] = useControllableEventValue(props, {
38+
valuePropName: 'checked',
39+
defaultValuePropName: 'defaultChecked'
40+
});
41+
checked = checked ?? false;
4242
let { disabled } = props;
4343

4444
const groupContext = useContext(CheckboxGroupContext);
45-
if (groupContext && props.value !== undefined) {
45+
if (groupContext && props.value !== undefined ) {
4646
checked = includes(groupContext.value, props.value);
47-
setChecked = (changedChecked: boolean) => {
48-
if (changedChecked) {
47+
setChecked = (e: ChangeEvent<HTMLInputElement>) => {
48+
if (e.target.checked === true) {
4949
groupContext.check(props.value);
5050
} else {
5151
groupContext.uncheck(props.value);
@@ -94,11 +94,8 @@ const Checkbox = forwardRef<CheckboxRef, CheckboxProps>((props, ref) => {
9494
checked={checked}
9595
onChange={(e: ChangeEvent<HTMLInputElement>) => {
9696
if (disabled) return;
97-
98-
if (!('checked' in props)) {
99-
setChecked(e.target.checked);
100-
}
101-
props.onChange?.(e);
97+
setChecked(e);
98+
// props.onChange?.(e);
10299
}}
103100
/>
104101
);
@@ -119,21 +116,6 @@ const Checkbox = forwardRef<CheckboxRef, CheckboxProps>((props, ref) => {
119116
};
120117
});
121118

122-
useEffect(() => {
123-
if (props.checked === undefined) return;
124-
if (props.checked === checked) return;
125-
126-
setChecked(
127-
getChecked(
128-
{
129-
checked: props.checked,
130-
defaultChecked: props.defaultChecked,
131-
},
132-
false,
133-
),
134-
);
135-
}, [props.checked, props.defaultChecked]);
136-
137119
if (groupContext?.type === 'button') {
138120
return (
139121
<label className={cls} style={props.style}>

packages/zarm/src/checkbox/CheckboxGroup.tsx

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
import { createBEM } from '@zarm-design/bem';
2-
import React, { FC, useContext, useEffect, useState } from 'react';
3-
import isEqual from 'lodash/isEqual';
2+
import React, { FC, useContext } from 'react';
43
import { ConfigContext } from '../config-provider';
54
import List from '../list';
65
import type { HTMLProps } from '../utils/utilityTypes';
76
import { CheckboxGroupContext } from './context';
8-
import type { BaseCheckboxGroupProps, CheckboxValue } from './interface';
7+
import type { BaseCheckboxGroupProps } from './interface';
8+
import useSelect from '../use-select';
9+
910

1011
export interface CheckboxGroupCssVars {
1112
'--group-spacing-vertical'?: React.CSSProperties['marginBottom'];
1213
'--group-spacing-horizontal'?: React.CSSProperties['marginRight'];
1314
}
1415

15-
const getValue = (props: CheckboxGroupProps, defaultValue?: CheckboxValue[]) => {
16-
return props.value ?? props.defaultValue ?? defaultValue;
17-
};
16+
// const getValue = (props: CheckboxGroupProps, defaultValue?: CheckboxValue[]) => {
17+
// return props.value ?? props.defaultValue ?? defaultValue;
18+
// };
1819

1920
export type CheckboxGroupProps = BaseCheckboxGroupProps & HTMLProps<CheckboxGroupCssVars>;
2021

2122
const CheckboxGroup: FC<CheckboxGroupProps> = (props) => {
22-
const [value, setValue] = useState(getValue(props, []));
23+
const [value, setValue] = useSelect({
24+
...props,
25+
multiple: true,
26+
});
2327
const { type, block, disabled, iconAlign, className, style } = props;
2428
const { prefixCls } = useContext(ConfigContext);
2529

@@ -33,13 +37,6 @@ const CheckboxGroup: FC<CheckboxGroupProps> = (props) => {
3337
className,
3438
]);
3539

36-
useEffect(() => {
37-
if (props.value === undefined) return;
38-
if (isEqual(props.value, value)) return;
39-
40-
setValue(getValue(props, []));
41-
}, [props.value]);
42-
4340
return (
4441
<CheckboxGroupContext.Provider
4542
value={{
@@ -49,14 +46,10 @@ const CheckboxGroup: FC<CheckboxGroupProps> = (props) => {
4946
disabled,
5047
iconAlign,
5148
check: (v) => {
52-
const values = [...value, v];
53-
setValue(values);
54-
props.onChange?.(values);
49+
setValue(v);
5550
},
5651
uncheck: (v) => {
57-
const values = value.filter((item) => item !== v);
58-
setValue(values);
59-
props.onChange?.(values);
52+
setValue(v);
6053
},
6154
}}
6255
>

packages/zarm/src/checkbox/demo.md

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ ReactDOM.render(
213213

214214
```jsx
215215
import { List, Checkbox } from 'zarm';
216-
import { Star, StarFill, Success, Close } from '@zarm-design/icons';
216+
import { Star, StarFill, Success, Close } from '@zarm-design/icons';
217217

218218
ReactDOM.render(
219219
<List>
@@ -264,8 +264,10 @@ const Demo = () => {
264264
const checkboxRef = useRef();
265265

266266
return (
267-
<Checkbox ref={checkboxRef} value={props.value}>
268-
{({ checked }) => (
267+
<Checkbox
268+
ref={checkboxRef}
269+
value={props.value}
270+
render={({ checked }) => (
269271
<div
270272
style={{
271273
position: 'relative',
@@ -293,7 +295,7 @@ const Demo = () => {
293295
{props.label}
294296
</div>
295297
)}
296-
</Checkbox>
298+
/>
297299
);
298300
};
299301
return (
@@ -326,26 +328,26 @@ ReactDOM.render(<Demo />, mountNode);
326328
| 属性 | 类型 | 默认值 | 说明 |
327329
| :------------- | :----------------------------------------------- | :----- | :-------------------------------------------------- |
328330
| disabled | boolean | false | 是否禁用 |
329-
| value | number \| string | - ||
331+
| value | number \| string | - ||
330332
| checked | boolean | false | 当前是否选中 |
331333
| defaultChecked | boolean | false | 初始是否选中 |
332-
| indeterminate | boolean | false | 当前是否为半选状态 |
334+
| indeterminate | boolean | false | 当前是否为半选状态 |
333335
| id | string | - | 方便外部带有 for 属性的 label 标签控制当前 checkbox |
334336
| onChange | (event: ChangeEvent\<HTMLInputElement\>) => void | - | 值变化时触发的回调函数 |
335-
| renderIcon | (props: number \| string) => React.ReactNode | - | 自定义图标渲染函数 |
336-
| render | (props: number \| string) => React.ReactNode | - | 自定义样式渲染函数 |
337+
| renderIcon | (props: number \| string) => React.ReactNode | - | 自定义图标渲染函数 |
338+
| render | (props: number \| string) => React.ReactNode | - | 自定义样式渲染函数 |
337339

338340
### Checkbox.Group
339341

340-
| 属性 | 类型 | 默认值 | 说明 |
341-
| :----------- | :------------------------------------- | :------- | :-------------------------------------------------- |
342-
| type | string | - | 显示类型,可选值 `button``list` |
343-
| value | number[] \| string[] | [] | 选中值 |
344-
| defaultValue | number[] \| string[] | [] | 初始选中值 |
345-
| disabled | boolean | false | 是否禁用 |
346-
| block | boolean | false | 子项是否为块级元素 |
347-
| iconAlign | string | 'before' | type 为`list`时图标的位置,可选值 `before``after` |
348-
| onChange | (values: number[] \| string[]) => void | - | 值变化时触发的回调函数 |
342+
| 属性 | 类型 | 默认值 | 说明 |
343+
| :------------ | :------------------------------------- | :------- | :-------------------------------------------------- |
344+
| type | string | - | 显示类型,可选值 `button``list` |
345+
| value | number[] \| string[] | [] | 选中值 |
346+
| defaultValue | number[] \| string[] | [] | 初始选中值 |
347+
| disabled | boolean | false | 是否禁用 |
348+
| block | boolean | false | 子项是否为块级元素 |
349+
| iconAlign | string | 'before' | type 为`list`时图标的位置,可选值 `before``after` |
350+
| onChange | (values: number[] \| string[]) => void | - | 值变化时触发的回调函数 |
349351

350352
## CSS 变量
351353

@@ -379,7 +381,6 @@ ReactDOM.render(<Demo />, mountNode);
379381
| --group-spacing-horizontal | '24px' | 组合使用时的横向间距 |
380382

381383
## Checkbox 指令式 API
382-
383384
```js
384385
// 选择
385386
ref.current.check();

0 commit comments

Comments
 (0)