Skip to content

Commit 90741fc

Browse files
authored
feat(useMergeOption): add useMergeOption (#577)
1 parent b238b49 commit 90741fc

File tree

5 files changed

+119
-0
lines changed

5 files changed

+119
-0
lines changed

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export { default as useDebounce } from './useDebounce';
3535
export { default as useIntersectionObserver } from './useIntersectionObserver';
3636
export { default as useList } from './useList';
3737
export { default as useMeasure } from './useMeasure';
38+
export { default as useMergeOption } from './useMergeOption';
3839
export { default as useModal } from './useModal';
3940
export { default as useTyping } from './useTyping';
4041
export { default as useWindowSwitchListener } from './useWindowSwitchListener';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { renderHook } from '@testing-library/react-hooks';
2+
3+
import useMergeOption from '..';
4+
5+
describe('Test useMergeOption', () => {
6+
test('should return default value when state is false', () => {
7+
const { result } = renderHook(() => useMergeOption(false, { day: true }));
8+
expect(result.current).toEqual({ disabled: true, options: { day: true } });
9+
});
10+
11+
test('should return default value when state is true', () => {
12+
const { result } = renderHook(() => useMergeOption(true, { day: true }));
13+
expect(result.current).toEqual({ disabled: false, options: { day: true } });
14+
});
15+
16+
test('should return merged value when state is an object', () => {
17+
const { result } = renderHook(() => useMergeOption({ day: false }, { day: true }));
18+
expect(result.current).toEqual({ disabled: false, options: { day: false } });
19+
});
20+
});

src/useMergeOption/demos/basic.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React, { useState } from 'react';
2+
import { Segmented } from 'antd';
3+
import { useMergeOption } from 'dt-react-component';
4+
import type { MergeOption } from 'dt-react-component/useMergeOption';
5+
6+
type ExampleState = MergeOption<{ day?: boolean }>;
7+
8+
export default function Basic() {
9+
const [state, setState] = useState<ExampleState>(false);
10+
11+
const merged = useMergeOption(state, { day: true });
12+
13+
const getValue = () => {
14+
if (state === false) return 0;
15+
if (state === true) return 2;
16+
return 1;
17+
};
18+
const setValue = (value: number) => {
19+
setState([false, { day: false }, true][value]);
20+
};
21+
22+
return (
23+
<>
24+
<label>Change value:</label>
25+
<Segmented
26+
value={getValue()}
27+
options={[
28+
{
29+
label: 'false',
30+
value: 0,
31+
},
32+
{
33+
label: `{ day: false }`,
34+
value: 1,
35+
},
36+
{
37+
label: 'true',
38+
value: 2,
39+
},
40+
]}
41+
onChange={(val) => setValue(val as number)}
42+
/>
43+
<pre style={{ marginTop: 8, border: '1px solid #eee', padding: 8 }}>
44+
{JSON.stringify(merged, null, 2)}
45+
</pre>
46+
</>
47+
);
48+
}

src/useMergeOption/index.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: useMergeOption 合并配置项
3+
group: Hooks
4+
toc: content
5+
---
6+
7+
# useMergeOption
8+
9+
## 何时使用
10+
11+
需要合并配置项
12+
13+
## 示例
14+
15+
<code src="./demos/basic.tsx" title="基础使用"></code>
16+
17+
## API
18+
19+
### Returns
20+
21+
| 参数 | 说明 | 类型 | 默认值 |
22+
| -------- | -------------- | ------------------------------- | ------ |
23+
| disabled | 是否禁用 | `boolean` | - |
24+
| options | 合并后的配置项 | `T extends Record<string, any>` | - |

src/useMergeOption/index.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { useMemo } from 'react';
2+
3+
export type MergeOption<T extends Record<string, any>> = boolean | T;
4+
5+
export type ReturnMergeOption<T extends Record<string, any>> = {
6+
disabled: boolean;
7+
options: T;
8+
};
9+
10+
export default function useMergeOption<T extends Record<string, any>>(
11+
opt: MergeOption<T>,
12+
defaultOpt?: T
13+
): ReturnMergeOption<T> {
14+
return useMemo(() => {
15+
if (typeof opt === 'object' && !!opt) {
16+
return {
17+
disabled: false,
18+
options: { ...defaultOpt, ...opt },
19+
};
20+
}
21+
return {
22+
disabled: !opt,
23+
options: <T>{ ...defaultOpt },
24+
};
25+
}, [opt]);
26+
}

0 commit comments

Comments
 (0)