From 049c9350a83d39b4589f72c9e9a7ef77bfe2ccec Mon Sep 17 00:00:00 2001 From: lich-yoo Date: Mon, 6 Nov 2023 10:07:39 +0800 Subject: [PATCH 1/4] feat(useSelections): add clearAll result --- .../src/useSelections/__tests__/index.test.ts | 34 +++++++++++++++++++ .../hooks/src/useSelections/index.en-US.md | 1 + packages/hooks/src/useSelections/index.ts | 6 ++++ .../hooks/src/useSelections/index.zh-CN.md | 1 + 4 files changed, 42 insertions(+) diff --git a/packages/hooks/src/useSelections/__tests__/index.test.ts b/packages/hooks/src/useSelections/__tests__/index.test.ts index ea943f0f90..c46ab09df3 100644 --- a/packages/hooks/src/useSelections/__tests__/index.test.ts +++ b/packages/hooks/src/useSelections/__tests__/index.test.ts @@ -1,4 +1,5 @@ import { act, renderHook } from '@testing-library/react'; +import { useState } from 'react'; import useSelections from '../index'; const data = [1, 2, 3]; @@ -122,4 +123,37 @@ describe('useSelections', () => { expect(result.current.allSelected).toBe(true); expect(result.current.partiallySelected).toBe(false); }); + + it('clearAll should work correct', async () => { + const { result } = renderHook(() => { + const [list, setList] = useState(data); + const hook = useSelections(list); + return { setList, hook }; + }); + const { setSelected, unSelectAll, clearAll } = result.current.hook; + + act(() => { + setSelected([1, 2, 3]); + }); + expect(result.current.hook.selected).toEqual([1, 2, 3]); + expect(result.current.hook.allSelected).toBe(true); + + act(() => { + result.current.setList([3, 4, 5]); + }); + expect(result.current.hook.allSelected).toBe(false); + + act(() => { + unSelectAll(); + }); + expect(result.current.hook.selected).toEqual([1, 2]); + + act(() => { + clearAll(); + }); + expect(result.current.hook.selected).toEqual([]); + expect(result.current.hook.allSelected).toEqual(false); + expect(result.current.hook.noneSelected).toBe(true); + expect(result.current.hook.partiallySelected).toBe(false); + }); }); diff --git a/packages/hooks/src/useSelections/index.en-US.md b/packages/hooks/src/useSelections/index.en-US.md index 991ae315bc..7518f3cd3c 100644 --- a/packages/hooks/src/useSelections/index.en-US.md +++ b/packages/hooks/src/useSelections/index.en-US.md @@ -34,4 +34,5 @@ const result: Result = useSelections(items: T[], defaultSelected?: T[]); | toggle | Toggle single item select status | `(value: T) => void` | | selectAll | Select all items | `() => void` | | unSelectAll | UnSelect all items | `() => void` | +| clearAll | Clear all selected | `() => void` | | toggleAll | Toggle select all items | `() => void` | diff --git a/packages/hooks/src/useSelections/index.ts b/packages/hooks/src/useSelections/index.ts index e9b5b4e9a5..0827a385b4 100644 --- a/packages/hooks/src/useSelections/index.ts +++ b/packages/hooks/src/useSelections/index.ts @@ -40,6 +40,11 @@ export default function useSelections(items: T[], defaultSelected: T[] = []) setSelected(Array.from(selectedSet)); }; + const clearAll = () => { + selectedSet.clear(); + setSelected([]); + }; + const noneSelected = useMemo(() => items.every((o) => !selectedSet.has(o)), [items, selectedSet]); const allSelected = useMemo( @@ -66,6 +71,7 @@ export default function useSelections(items: T[], defaultSelected: T[] = []) toggle: useMemoizedFn(toggle), selectAll: useMemoizedFn(selectAll), unSelectAll: useMemoizedFn(unSelectAll), + clearAll: useMemoizedFn(clearAll), toggleAll: useMemoizedFn(toggleAll), } as const; } diff --git a/packages/hooks/src/useSelections/index.zh-CN.md b/packages/hooks/src/useSelections/index.zh-CN.md index 084fbeb933..995c6f03f2 100644 --- a/packages/hooks/src/useSelections/index.zh-CN.md +++ b/packages/hooks/src/useSelections/index.zh-CN.md @@ -34,4 +34,5 @@ const result: Result = useSelections(items: T[], defaultSelected?: T[]); | toggle | 反选单个元素 | `(value: T) => void` | | selectAll | 选择全部元素 | `() => void` | | unSelectAll | 取消选择全部元素 | `() => void` | +| clearAll | 清除所有选中元素 | `() => void` | | toggleAll | 反选全部元素 | `() => void` | From f1d67f1568850eafe932309755a8cb4ddc45f8ec Mon Sep 17 00:00:00 2001 From: liuyib <1656081615@qq.com> Date: Mon, 6 Nov 2023 15:30:13 +0800 Subject: [PATCH 2/4] docs: update docs and code style --- .../hooks/src/useSelections/index.en-US.md | 13 ++++++- packages/hooks/src/useSelections/index.ts | 10 ++--- .../hooks/src/useSelections/index.zh-CN.md | 39 ++++++++++++------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/packages/hooks/src/useSelections/index.en-US.md b/packages/hooks/src/useSelections/index.en-US.md index 7518f3cd3c..b5bd7b85bc 100644 --- a/packages/hooks/src/useSelections/index.en-US.md +++ b/packages/hooks/src/useSelections/index.en-US.md @@ -19,11 +19,20 @@ This hook is used for Checkbox group, supports multiple selection, single select const result: Result = useSelections(items: T[], defaultSelected?: T[]); ``` +Note: Generic type `T` currently only supports [JavaScript primitive data types](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) and does not support object. + +### Params + +| Property | Description | Type | Default | +| --------------- | ---------------------- | ----- | ------- | +| items | Data items | `T[]` | - | +| defaultSelected | Default selected items | `T[]` | - | + ### Result | Property | Description | Type | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | -| selected | Selected Items | `T[]` | +| selected | Selected items | `T[]` | | allSelected | Is all items selected | `boolean` | | noneSelected | Is no item selected | `boolean` | | partiallySelected | Is partially items selected | `boolean` | @@ -34,5 +43,5 @@ const result: Result = useSelections(items: T[], defaultSelected?: T[]); | toggle | Toggle single item select status | `(value: T) => void` | | selectAll | Select all items | `() => void` | | unSelectAll | UnSelect all items | `() => void` | -| clearAll | Clear all selected | `() => void` | | toggleAll | Toggle select all items | `() => void` | +| clearAll | Clear all selected (In general, `clearAll` is equivalent to `unSelectAll`. If the items is dynamic, `clearAll` will clear "all selected data", while `unSelectAll` will only clear "the currently selected data in the items".) | `() => void` | diff --git a/packages/hooks/src/useSelections/index.ts b/packages/hooks/src/useSelections/index.ts index 0827a385b4..67a11c704b 100644 --- a/packages/hooks/src/useSelections/index.ts +++ b/packages/hooks/src/useSelections/index.ts @@ -40,11 +40,6 @@ export default function useSelections(items: T[], defaultSelected: T[] = []) setSelected(Array.from(selectedSet)); }; - const clearAll = () => { - selectedSet.clear(); - setSelected([]); - }; - const noneSelected = useMemo(() => items.every((o) => !selectedSet.has(o)), [items, selectedSet]); const allSelected = useMemo( @@ -59,6 +54,11 @@ export default function useSelections(items: T[], defaultSelected: T[] = []) const toggleAll = () => (allSelected ? unSelectAll() : selectAll()); + const clearAll = () => { + selectedSet.clear(); + setSelected([]); + }; + return { selected, noneSelected, diff --git a/packages/hooks/src/useSelections/index.zh-CN.md b/packages/hooks/src/useSelections/index.zh-CN.md index 995c6f03f2..b7aade2169 100644 --- a/packages/hooks/src/useSelections/index.zh-CN.md +++ b/packages/hooks/src/useSelections/index.zh-CN.md @@ -19,20 +19,29 @@ nav: const result: Result = useSelections(items: T[], defaultSelected?: T[]); ``` +注:泛型 `T` 目前只支持 [JavaScript 原始数据类型](https://developer.mozilla.org/en-US/docs/Glossary/Primitive),不支持对象。 + +### Params + +| 参数 | 说明 | 类型 | 默认值 | +| --------------- | -------------- | ----- | ------ | +| items | 元素列表 | `T[]` | - | +| defaultSelected | 默认选择的元素 | `T[]` | - | + ### Result -| 参数 | 说明 | 类型 | -| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | -| selected | 已经选择的元素 | `T[]` | -| allSelected | 是否全选 | `boolean` | -| noneSelected | 是否一个都没有选择 | `boolean` | -| partiallySelected | 是否半选 | `boolean` | -| isSelected | 是否被选择 | `(value: T) => boolean` | -| setSelected | 选择多个元素。多次执行时,后面的返回值会覆盖前面的,因此如果希望合并多次操作的结果,需要手动处理:`setSelected((oldArray) => oldArray.concat(newArray))` | `(value: T[]) => void \| (value: (prevState: T[]) => T[]) => void` | -| select | 选择单个元素 | `(value: T) => void` | -| unSelect | 取消选择单个元素 | `(value: T) => void` | -| toggle | 反选单个元素 | `(value: T) => void` | -| selectAll | 选择全部元素 | `() => void` | -| unSelectAll | 取消选择全部元素 | `() => void` | -| clearAll | 清除所有选中元素 | `() => void` | -| toggleAll | 反选全部元素 | `() => void` | +| 参数 | 说明 | 类型 | +| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| selected | 已经选择的元素 | `T[]` | +| allSelected | 是否全选 | `boolean` | +| noneSelected | 是否一个都没有选择 | `boolean` | +| partiallySelected | 是否半选 | `boolean` | +| isSelected | 是否被选择 | `(value: T) => boolean` | +| setSelected | 选择多个元素。多次执行时,后面的返回值会覆盖前面的,因此如果希望合并多次操作的结果,需要手动处理:`setSelected((oldArray) => oldArray.concat(newArray))` | `(value: T[]) => void \| (value: (prevState: T[]) => T[]) => void` | +| select | 选择单个元素 | `(value: T) => void` | +| unSelect | 取消选择单个元素 | `(value: T) => void` | +| toggle | 反选单个元素 | `(value: T) => void` | +| selectAll | 选择全部元素 | `() => void` | +| unSelectAll | 取消选择全部元素 | `() => void` | +| toggleAll | 反选全部元素 | `() => void` | +| clearAll | 清除所有选中元素(一般情况下,`clearAll` 等价于 `unSelectAll`。如果元素列表是动态的,则 `clearAll` 会清除掉“所有选中过的元素”,而 `unSelectAll` 只会清除掉“当前元素列表里选中的元素”) | `() => void` | From 28e02f860ed5a17c96323c8003b72980faca783c Mon Sep 17 00:00:00 2001 From: liuyib <1656081615@qq.com> Date: Wed, 24 Apr 2024 20:29:56 +0800 Subject: [PATCH 3/4] refactor: resolve conflict --- packages/hooks/src/useSelections/index.en-US.md | 8 +++++--- packages/hooks/src/useSelections/index.ts | 2 +- packages/hooks/src/useSelections/index.zh-CN.md | 8 +++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/hooks/src/useSelections/index.en-US.md b/packages/hooks/src/useSelections/index.en-US.md index b659e47cf0..474b1c460a 100644 --- a/packages/hooks/src/useSelections/index.en-US.md +++ b/packages/hooks/src/useSelections/index.en-US.md @@ -38,9 +38,11 @@ const result: Result = useSelections(items: T[], defaultSelected?: T[]); ### Params -| Property | Description | Type | Default | -| --------------- | ---------------------- | ----- | ------- | -| items | Data items | `T[]` | - | + +| Property | Description | Type | Default | +| --- | --- | --- | --- | +| items | Data items | `T[]` | - | +| options | Optional configuration | `Options` | - | ### Options diff --git a/packages/hooks/src/useSelections/index.ts b/packages/hooks/src/useSelections/index.ts index 8cf2036569..e98ce0fa3b 100644 --- a/packages/hooks/src/useSelections/index.ts +++ b/packages/hooks/src/useSelections/index.ts @@ -95,7 +95,7 @@ export default function useSelections(items: T[], options?: T[] | Options) const toggleAll = () => (allSelected ? unSelectAll() : selectAll()); const clearAll = () => { - selectedSet.clear(); + selectedMap.clear(); setSelected([]); }; diff --git a/packages/hooks/src/useSelections/index.zh-CN.md b/packages/hooks/src/useSelections/index.zh-CN.md index 382bf257bc..022216b965 100644 --- a/packages/hooks/src/useSelections/index.zh-CN.md +++ b/packages/hooks/src/useSelections/index.zh-CN.md @@ -38,9 +38,11 @@ const result: Result = useSelections(items: T[], defaultSelected?: T[]); ### Params -| 参数 | 说明 | 类型 | 默认值 | -| --------------- | -------------- | ----- | ------ | -| items | 元素列表 | `T[]` | - | + +| 参数 | 说明 | 类型 | 默认值 | +| --- | --- | --- | --- | +| items | 元素列表 | `T[]` | - | +| options | 可选配置项 | `Options` | - | ### Options From 00586b0c384e2fa030d9df06d6ea42c65b5d257c Mon Sep 17 00:00:00 2001 From: liuyib <1656081615@qq.com> Date: Wed, 24 Apr 2024 20:33:38 +0800 Subject: [PATCH 4/4] docs: update --- packages/hooks/src/useSelections/index.en-US.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/hooks/src/useSelections/index.en-US.md b/packages/hooks/src/useSelections/index.en-US.md index 474b1c460a..8cf96832f5 100644 --- a/packages/hooks/src/useSelections/index.en-US.md +++ b/packages/hooks/src/useSelections/index.en-US.md @@ -68,4 +68,4 @@ const result: Result = useSelections(items: T[], defaultSelected?: T[]); | selectAll | Select all items | `() => void` | | unSelectAll | UnSelect all items | `() => void` | | toggleAll | Toggle select all items | `() => void` | -| clearAll | Clear all selected (In general, `clearAll` is equivalent to `unSelectAll`. If the items is dynamic, `clearAll` will clear "all selected data", while `unSelectAll` will only clear "the currently selected data in the items".) | `() => void` | +| clearAll | Clear all selected (In general, `clearAll` is equivalent to `unSelectAll`. If the items is dynamic, `clearAll` will clear "all selected data", while `unSelectAll` will only clear "the currently selected data in the items") | `() => void` |