From a07610e448ac5f79fde06aadec826191ecfcc893 Mon Sep 17 00:00:00 2001 From: nathanlao11 Date: Wed, 16 Oct 2024 16:28:44 -0700 Subject: [PATCH 1/2] feat: support option in onChange handler --- src/TreeSelect.tsx | 24 +- src/interface.ts | 13 + tests/Select.props.spec.js | 3 + .../Select.checkable.spec.tsx.snap | 470 +++++++++--------- .../Select.multiple.spec.js.snap | 66 +-- tests/__snapshots__/Select.spec.tsx.snap | 452 +++++++++-------- 6 files changed, 559 insertions(+), 469 deletions(-) diff --git a/src/TreeSelect.tsx b/src/TreeSelect.tsx index e8046954..e05afa2c 100644 --- a/src/TreeSelect.tsx +++ b/src/TreeSelect.tsx @@ -34,6 +34,7 @@ import type { DefaultValueType, FieldNames, LegacyDataNode, + DefaultOptionType, } from './interface'; export interface TreeSelectProps @@ -45,7 +46,11 @@ export interface TreeSelectProps>> Value value?: ValueType; defaultValue?: ValueType; - onChange?: (value: ValueType, labelList: React.ReactNode[], extra: ChangeEventExtra) => void; + onChange?: ( + value: ValueType, + labelList: React.ReactNode[], + extra: ChangeEventExtra & { option?: DefaultOptionType }, + ) => void; // >>> Search searchValue?: string; @@ -410,7 +415,7 @@ const TreeSelect = React.forwardRef((props, ref) const triggerChange = useRefFunc( ( newRawValues: SafeKey[], - extra: { triggerValue?: SafeKey; selected?: boolean }, + extra: { triggerValue?: SafeKey; selected?: boolean; option?: DefaultOptionType }, source: SelectSource, ) => { const labeledValues = convert2LabelValues(newRawValues); @@ -456,7 +461,8 @@ const TreeSelect = React.forwardRef((props, ref) // [Legacy] Always return as array contains label & value preValue: rawLabeledValues, triggerValue, - } as ChangeEventExtra; + option: extra.option, + } as ChangeEventExtra & { option?: DefaultOptionType }; // [Legacy] Fill legacy data if user query. // This is expansive that we only fill when user query @@ -505,7 +511,11 @@ const TreeSelect = React.forwardRef((props, ref) // Never be falsy but keep it safe if (!mergedMultiple) { // Single mode always set value - triggerChange([selectedValue], { selected: true, triggerValue: selectedValue }, 'option'); + triggerChange( + [selectedValue], + { selected: true, triggerValue: selectedValue, option: node as DefaultOptionType }, + 'option', + ); } else { let newRawValues = selected ? [...rawValues, selectedValue] @@ -535,7 +545,11 @@ const TreeSelect = React.forwardRef((props, ref) ...checkedKeys.map(key => keyEntities[key as SafeKey].node[mergedFieldNames.value]), ]; } - triggerChange(newRawValues, { selected, triggerValue: selectedValue }, source || 'option'); + triggerChange( + newRawValues, + { selected, triggerValue: selectedValue, option: node as DefaultOptionType }, + source || 'option', + ); } // Trigger select event diff --git a/src/interface.ts b/src/interface.ts index ccacc8cb..54d3ed88 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -3,6 +3,19 @@ import type { SafeKey, Key, DataNode as TreeDataNode } from 'rc-tree/lib/interfa export type { SafeKey, Key }; +export interface BaseOptionType { + disabled?: boolean; + className?: string; + title?: string; + [name: string]: any; +} + +export interface DefaultOptionType extends BaseOptionType { + label?: React.ReactNode; + value?: string | number | null; + children?: Omit[]; +} + export interface DataNode extends Record, Omit { key?: Key; value?: SafeKey; diff --git a/tests/Select.props.spec.js b/tests/Select.props.spec.js index 6055a84a..6fa8d05a 100644 --- a/tests/Select.props.spec.js +++ b/tests/Select.props.spec.js @@ -324,6 +324,7 @@ describe('TreeSelect.props', () => { }), ], checked: true, + option: expect.anything(), preValue: [], triggerNode: expect.anything(), triggerValue: 'Value 0', @@ -342,6 +343,7 @@ describe('TreeSelect.props', () => { }), ], checked: true, + option: expect.anything(), preValue: [], triggerNode: expect.anything(), triggerValue: 'Value 0', @@ -360,6 +362,7 @@ describe('TreeSelect.props', () => { }), ], checked: true, + option: expect.anything(), preValue: [], triggerNode: expect.anything(), triggerValue: 'Value 0', diff --git a/tests/__snapshots__/Select.checkable.spec.tsx.snap b/tests/__snapshots__/Select.checkable.spec.tsx.snap index 5fc75a90..1f498737 100644 --- a/tests/__snapshots__/Select.checkable.spec.tsx.snap +++ b/tests/__snapshots__/Select.checkable.spec.tsx.snap @@ -8,121 +8,125 @@ exports[`TreeSelect.checkable uncheck remove by selector not treeCheckStrictly 1
-
- - 0 - - - -
-
- +
- 0-0 - - - -
-
- +
- 0-0-0 - - - -
-
+
-
+
-
-
- + +
-
- - 0 - - - -
-
- +
- 0-0 - - - -
-
- +
- 0-0-0 - - - -
-
+
-
+
-
-
+
-
-
- + + `; diff --git a/tests/__snapshots__/Select.spec.tsx.snap b/tests/__snapshots__/Select.spec.tsx.snap index 5b633006..1442f0c2 100644 --- a/tests/__snapshots__/Select.spec.tsx.snap +++ b/tests/__snapshots__/Select.spec.tsx.snap @@ -8,28 +8,32 @@ exports[`TreeSelect.basic render renders TreeNode correctly 1`] = ` class="rc-tree-select-selector" > - + + + -
- + + + -
-
-
- + + `; @@ -455,29 +467,33 @@ exports[`TreeSelect.basic render renders disabled correctly 1`] = ` class="rc-tree-select-selector" > - + + + - `; @@ -489,45 +505,49 @@ exports[`TreeSelect.basic render renders tree correctly 1`] = `
-
-
- + + `; @@ -541,28 +561,32 @@ exports[`TreeSelect.basic render renders treeDataSimpleMode correctly 1`] = ` class="rc-tree-select-selector" > - + + + -
- + + + -
- + + + -
- + + + -
- + + + -
Date: Tue, 12 Nov 2024 22:25:46 -0800 Subject: [PATCH 2/2] fix: rename and add test case with treeNode data --- src/TreeSelect.tsx | 8 ++++---- tests/Select.props.spec.js | 24 +++++++++++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/TreeSelect.tsx b/src/TreeSelect.tsx index e05afa2c..065b9f6f 100644 --- a/src/TreeSelect.tsx +++ b/src/TreeSelect.tsx @@ -415,7 +415,7 @@ const TreeSelect = React.forwardRef((props, ref) const triggerChange = useRefFunc( ( newRawValues: SafeKey[], - extra: { triggerValue?: SafeKey; selected?: boolean; option?: DefaultOptionType }, + extra: { triggerValue?: SafeKey; selected?: boolean; nodes?: DefaultOptionType }, source: SelectSource, ) => { const labeledValues = convert2LabelValues(newRawValues); @@ -461,7 +461,7 @@ const TreeSelect = React.forwardRef((props, ref) // [Legacy] Always return as array contains label & value preValue: rawLabeledValues, triggerValue, - option: extra.option, + option: extra.nodes, } as ChangeEventExtra & { option?: DefaultOptionType }; // [Legacy] Fill legacy data if user query. @@ -513,7 +513,7 @@ const TreeSelect = React.forwardRef((props, ref) // Single mode always set value triggerChange( [selectedValue], - { selected: true, triggerValue: selectedValue, option: node as DefaultOptionType }, + { selected: true, triggerValue: selectedValue, nodes: node as DefaultOptionType }, 'option', ); } else { @@ -547,7 +547,7 @@ const TreeSelect = React.forwardRef((props, ref) } triggerChange( newRawValues, - { selected, triggerValue: selectedValue, option: node as DefaultOptionType }, + { selected, triggerValue: selectedValue, nodes: node as DefaultOptionType }, source || 'option', ); } diff --git a/tests/Select.props.spec.js b/tests/Select.props.spec.js index 6fa8d05a..3f576d73 100644 --- a/tests/Select.props.spec.js +++ b/tests/Select.props.spec.js @@ -310,6 +310,24 @@ describe('TreeSelect.props', () => { }); describe('showCheckedStrategy', () => { + const treeData = { + key: 'key 0', + title: 'Title 0', + value: 'Value 0', + children: [ + { + key: 'key 0-0', + title: 'Title 0-0', + value: 'Value 0-0', + }, + { + key: 'key 0-1', + title: 'Title 0-1', + value: 'Value 0-1', + }, + ], + }; + const testList = [ { strategy: SHOW_ALL, @@ -324,7 +342,7 @@ describe('TreeSelect.props', () => { }), ], checked: true, - option: expect.anything(), + option: expect.objectContaining(treeData), preValue: [], triggerNode: expect.anything(), triggerValue: 'Value 0', @@ -343,7 +361,7 @@ describe('TreeSelect.props', () => { }), ], checked: true, - option: expect.anything(), + option: expect.objectContaining(treeData), preValue: [], triggerNode: expect.anything(), triggerValue: 'Value 0', @@ -362,7 +380,7 @@ describe('TreeSelect.props', () => { }), ], checked: true, - option: expect.anything(), + option: expect.objectContaining(treeData), preValue: [], triggerNode: expect.anything(), triggerValue: 'Value 0',