Skip to content

Commit 7f8d76e

Browse files
committed
feat: internal props can skip onChange onSelect event
1 parent a153cd0 commit 7f8d76e

File tree

3 files changed

+73
-15
lines changed

3 files changed

+73
-15
lines changed

src/OptionList.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ const OptionList: React.RefForwardingComponent<
131131
// ========================== Values ==========================
132132
const onSelectValue = (value: RawValueType) => {
133133
if (value !== null) {
134+
console.log('-->', value, Array.from(values));
134135
onSelect(value, { selected: !values.has(value) });
135136
}
136137

src/generate.tsx

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ export interface SelectProps<OptionsType extends object[], ValueType> extends Re
148148
internalProps?: {
149149
mark?: string;
150150
onClear?: OnClear;
151+
skipTriggerChange?: boolean;
152+
skipTriggerSelect?: boolean;
153+
onRawSelect?: (value: RawValueType, option: OptionsType[number]) => void;
154+
onRawDeselect?: (value: RawValueType, option: OptionsType[number]) => void;
151155
};
152156
}
153157

@@ -289,6 +293,8 @@ export default function generateSelector<
289293
...restProps
290294
} = props;
291295

296+
const useInternalProps = internalProps.mark === INTERNAL_PROPS_MARK;
297+
292298
const domProps = omitDOMProps ? omitDOMProps(restProps) : restProps;
293299
DEFAULT_OMIT_PROPS.forEach(prop => {
294300
delete domProps[prop];
@@ -428,25 +434,41 @@ export default function generateSelector<
428434
);
429435

430436
const triggerSelect = (newValue: RawValueType, isSelect: boolean) => {
431-
const selectValue = (mergedLabelInValue
432-
? getLabeledValue(newValue, {
433-
options: mergedFlattenOptions,
434-
prevValue: baseValue,
435-
labelInValue: mergedLabelInValue,
436-
optionLabelProp: mergedOptionLabelProp,
437-
})
438-
: newValue) as SingleType<ValueType>;
439-
440437
const outOption = findValueOption([newValue], mergedFlattenOptions)[0];
441438

442-
if (isSelect && onSelect) {
443-
onSelect(selectValue, outOption);
444-
} else if (!isSelect && onDeselect) {
445-
onDeselect(selectValue, outOption);
439+
if (!internalProps.skipTriggerSelect) {
440+
// Skip trigger `onSelect` or `onDeselect` if configured
441+
const selectValue = (mergedLabelInValue
442+
? getLabeledValue(newValue, {
443+
options: mergedFlattenOptions,
444+
prevValue: baseValue,
445+
labelInValue: mergedLabelInValue,
446+
optionLabelProp: mergedOptionLabelProp,
447+
})
448+
: newValue) as SingleType<ValueType>;
449+
450+
if (isSelect && onSelect) {
451+
onSelect(selectValue, outOption);
452+
} else if (!isSelect && onDeselect) {
453+
onDeselect(selectValue, outOption);
454+
}
455+
}
456+
457+
// Trigger internal event
458+
if (useInternalProps) {
459+
if (isSelect && internalProps.onRawSelect) {
460+
internalProps.onRawSelect(newValue, outOption);
461+
} else if (!isSelect && internalProps.onRawDeselect) {
462+
internalProps.onRawDeselect(newValue, outOption);
463+
}
446464
}
447465
};
448466

449467
const triggerChange = (newRawValues: RawValueType[]) => {
468+
if (useInternalProps && internalProps.skipTriggerChange) {
469+
return;
470+
}
471+
450472
const outValues = toOuterValues<FlattenOptionsType<OptionsType>>(Array.from(newRawValues), {
451473
labelInValue: mergedLabelInValue,
452474
options: mergedFlattenOptions,
@@ -766,7 +788,7 @@ export default function generateSelector<
766788
let clearNode: React.ReactNode;
767789
const onClearMouseDown: React.MouseEventHandler<HTMLSpanElement> = () => {
768790
// Trigger internal `onClear` event
769-
if (internalProps.mark === INTERNAL_PROPS_MARK && internalProps.onClear) {
791+
if (useInternalProps && internalProps.onClear) {
770792
internalProps.onClear();
771793
}
772794

tests/Select.test.tsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1265,8 +1265,22 @@ describe('Select.Basic', () => {
12651265
expect(opt.props).toBeTruthy();
12661266
};
12671267

1268+
// We also test if internal hooks work here.
1269+
// Can be remove if not need in `rc-tree-select` anymore.
1270+
const onRawSelect = jest.fn();
1271+
const onRawDeselect = jest.fn();
1272+
12681273
const wrapper = mount(
1269-
<Select mode="multiple" onSelect={readPropsFunc} onDeselect={readPropsFunc}>
1274+
<Select
1275+
mode="multiple"
1276+
onSelect={readPropsFunc}
1277+
onDeselect={readPropsFunc}
1278+
internalProps={{
1279+
mark: INTERNAL_PROPS_MARK,
1280+
onRawSelect,
1281+
onRawDeselect,
1282+
}}
1283+
>
12701284
<Option value="light">Light</Option>
12711285
<Option value="bamboo">Bamboo</Option>
12721286
</Select>,
@@ -1277,13 +1291,15 @@ describe('Select.Basic', () => {
12771291
expect(errorSpy).toHaveBeenCalledWith(
12781292
'Warning: Return type is option instead of Option instance. Please read value directly instead of reading from `props`.',
12791293
);
1294+
expect(onRawSelect).toHaveBeenCalled();
12801295

12811296
errorSpy.mockReset();
12821297
resetWarned();
12831298
selectItem(wrapper);
12841299
expect(errorSpy).toHaveBeenCalledWith(
12851300
'Warning: Return type is option instead of Option instance. Please read value directly instead of reading from `props`.',
12861301
);
1302+
expect(onRawDeselect).toHaveBeenCalled();
12871303

12881304
errorSpy.mockRestore();
12891305
});
@@ -1311,6 +1327,25 @@ describe('Select.Basic', () => {
13111327

13121328
errorSpy.mockRestore();
13131329
});
1330+
1331+
// This test case can be safe remove
1332+
it('skip onChange', () => {
1333+
const onChange = jest.fn();
1334+
const wrapper = mount(
1335+
<Select
1336+
onChange={onChange}
1337+
internalProps={{ mark: INTERNAL_PROPS_MARK, skipTriggerChange: true }}
1338+
>
1339+
<Option value="light">Light</Option>
1340+
<Option value="bamboo">Bamboo</Option>
1341+
</Select>,
1342+
);
1343+
1344+
toggleOpen(wrapper);
1345+
selectItem(wrapper);
1346+
1347+
expect(onChange).not.toHaveBeenCalled();
1348+
});
13141349
});
13151350

13161351
it('not crash when options is null', () => {

0 commit comments

Comments
 (0)