Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100
"printWidth": 100,
"arrowParens": "avoid"
}
17 changes: 12 additions & 5 deletions examples/debug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,25 @@ class Demo extends React.Component {
allowClear
treeDefaultExpandAll
onChange={this.onChange}
labelRender={entity => {
let current = entity;
const nodes = [];

while (current) {
nodes.unshift(current.data.title);
current = current.parent;
}

return nodes.join('>');
}}
>
<TreeNode value="parent 1" title="parent 1" key="0-1">
<TreeNode value="parent 1-0" title="parent 1-0" key="0-1-1">
<TreeNode value="leaf1" title="my leaf" key="random" />
<TreeNode value="leaf2" title="your leaf" key="random1" />
</TreeNode>
<TreeNode value="parent 1-1" title="parent 1-1" key="random2">
<TreeNode
value="sss"
title={<b style={{ color: '#08c' }}>sss</b>}
key="random3"
/>
<TreeNode value="sss" title={<b style={{ color: '#08c' }}>sss</b>} key="random3" />
</TreeNode>
</TreeNode>
</TreeSelect>
Expand Down
43 changes: 27 additions & 16 deletions src/generate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import type {
ChangeEventExtra,
LegacyDataNode,
SelectSource,
FlattenDataNode,
} from './interface';
import {
flattenOptions,
Expand Down Expand Up @@ -130,6 +131,9 @@ export interface TreeSelectProps<ValueType = DefaultValueType>
// Legacy
/** `searchPlaceholder` has been removed since search box has been merged into input box */
searchPlaceholder?: React.ReactNode;

/** @private This is not standard API since we only used in `rc-cascader`. Do not use in your production */
labelRender?: (entity: FlattenDataNode) => React.ReactNode;
}

export default function generate(config: {
Expand All @@ -153,7 +157,7 @@ export default function generate(config: {
findValueOption,
omitDOMProps: (props: object) => {
const cloneProps = { ...props };
OMIT_PROPS.forEach((prop) => {
OMIT_PROPS.forEach(prop => {
delete cloneProps[prop];
});
return cloneProps;
Expand Down Expand Up @@ -195,6 +199,7 @@ export default function generate(config: {
onDropdownVisibleChange,
onSelect,
onDeselect,
labelRender,
} = props;
const mergedCheckable: React.ReactNode | boolean = treeCheckable || treeCheckStrictly;
const mergedMultiple = multiple || mergedCheckable;
Expand All @@ -211,7 +216,13 @@ export default function generate(config: {
return node.label || node.title;
};

const getTreeNodeLabelProp = (node: DataNode): React.ReactNode => {
const getTreeNodeLabelProp = (entity: FlattenDataNode): React.ReactNode => {
const node = entity.data;

if (labelRender) {
return labelRender(entity);
}

if (treeNodeLabelProp) {
return node[treeNodeLabelProp];
}
Expand Down Expand Up @@ -259,7 +270,7 @@ export default function generate(config: {
const existRawValues = [];

// Keep missing value in the cache
newRawValues.forEach((val) => {
newRawValues.forEach(val => {
if (getEntityByValue(val)) {
existRawValues.push(val);
} else {
Expand All @@ -274,7 +285,7 @@ export default function generate(config: {
const valueHalfCheckedKeys: RawValueType[] = [];
const newRawValues: RawValueType[] = [];

toArray(value).forEach((item) => {
toArray(value).forEach(item => {
if (item && typeof item === 'object' && 'value' in item) {
if (item.halfChecked && treeCheckStrictly) {
const entity = getEntityByValue(item.value);
Expand All @@ -290,11 +301,11 @@ export default function generate(config: {
// We need do conduction of values
if (treeConduction) {
const { missingRawValues, existRawValues } = splitRawValues(newRawValues);
const keyList = existRawValues.map((val) => getEntityByValue(val).key);
const keyList = existRawValues.map(val => getEntityByValue(val).key);

const { checkedKeys, halfCheckedKeys } = conductCheck(keyList, true, conductKeyEntities);
return [
[...missingRawValues, ...checkedKeys.map((key) => getEntityByKey(key).data.value)],
[...missingRawValues, ...checkedKeys.map(key => getEntityByKey(key).data.value)],
halfCheckedKeys,
];
}
Expand All @@ -319,7 +330,7 @@ export default function generate(config: {
if (onChange) {
let eventValues: RawValueType[] = newRawValues;
if (treeConduction && showCheckedStrategy !== 'SHOW_ALL') {
const keyList = newRawValues.map((val) => {
const keyList = newRawValues.map(val => {
const entity = getEntityByValue(val);
return entity ? entity.key : val;
});
Expand All @@ -329,7 +340,7 @@ export default function generate(config: {
conductKeyEntities,
);

eventValues = formattedKeyList.map((key) => {
eventValues = formattedKeyList.map(key => {
const entity = getEntityByKey(key);
return entity ? entity.data.value : key;
});
Expand All @@ -347,11 +358,11 @@ export default function generate(config: {
// We need fill half check back
if (treeCheckStrictly) {
const halfValues = rawHalfCheckedKeys
.map((key) => {
.map(key => {
const entity = getEntityByKey(key);
return entity ? entity.data.value : key;
})
.filter((val) => !eventValues.includes(val));
.filter(val => !eventValues.includes(val));

returnValues = [
...(returnValues as LabelValueType[]),
Expand Down Expand Up @@ -391,9 +402,9 @@ export default function generate(config: {
mergedMultiple ? returnValues : returnValues[0],
mergedLabelInValue
? null
: eventValues.map((val) => {
: eventValues.map(val => {
const entity = getEntityByValue(val);
return entity ? getTreeNodeLabelProp(entity.data) : null;
return entity ? getTreeNodeLabelProp(entity) : null;
}),
additionalInfo,
);
Expand All @@ -417,11 +428,11 @@ export default function generate(config: {
if (treeConduction) {
// Should keep missing values
const { missingRawValues, existRawValues } = splitRawValues(newRawValues);
const keyList = existRawValues.map((val) => getEntityByValue(val).key);
const keyList = existRawValues.map(val => getEntityByValue(val).key);
const { checkedKeys } = conductCheck(keyList, true, conductKeyEntities);
newRawValues = [
...missingRawValues,
...checkedKeys.map((key) => getEntityByKey(key).data.value),
...checkedKeys.map(key => getEntityByKey(key).data.value),
];
}

Expand All @@ -445,15 +456,15 @@ export default function generate(config: {
// Remove keys if tree conduction
if (treeConduction) {
const { missingRawValues, existRawValues } = splitRawValues(newRawValues);
const keyList = existRawValues.map((val) => getEntityByValue(val).key);
const keyList = existRawValues.map(val => getEntityByValue(val).key);
const { checkedKeys } = conductCheck(
keyList,
{ checked: false, halfCheckedKeys: rawHalfCheckedKeys },
conductKeyEntities,
);
newRawValues = [
...missingRawValues,
...checkedKeys.map((key) => getEntityByKey(key).data.value),
...checkedKeys.map(key => getEntityByKey(key).data.value),
];
}

Expand Down
8 changes: 4 additions & 4 deletions src/hooks/useSelectValues.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import type { DefaultValueType } from 'rc-select/lib/interface/generator';
import type { DataEntity } from 'rc-tree/lib/interface';
import type { RawValueType, FlattenDataNode, Key, LabelValueType, DataNode } from '../interface';
import type { RawValueType, FlattenDataNode, Key, LabelValueType } from '../interface';
import type { SkipType } from './useKeyValueMapping';
import { getRawValueLabeled } from '../utils/valueUtil';
import type { CheckedStrategy } from '../utils/strategyUtil';
Expand All @@ -19,7 +19,7 @@ interface Config {
skipType?: SkipType,
ignoreDisabledCheck?: boolean,
) => FlattenDataNode;
getLabelProp: (node: DataNode) => React.ReactNode;
getLabelProp: (entity: FlattenDataNode) => React.ReactNode;
}

/** Return */
Expand All @@ -40,15 +40,15 @@ export default function useSelectValues(

if (treeConduction) {
const rawKeys = formatStrategyKeys(
rawValues.map((val) => {
rawValues.map(val => {
const entity = getEntityByValue(val);
return entity ? entity.key : val;
}),
showCheckedStrategy,
conductKeyEntities,
);

mergedRawValues = rawKeys.map((key) => {
mergedRawValues = rawKeys.map(key => {
const entity = getEntityByKey(key);
return entity ? entity.data.value : key;
});
Expand Down
22 changes: 11 additions & 11 deletions src/utils/valueUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ export function toArray<T>(value: T | T[]): T[] {
export function findValueOption(values: RawValueType[], options: CompatibleDataNode[]): DataNode[] {
const optionMap: Map<RawValueType, DataNode> = new Map();

options.forEach((flattenItem) => {
options.forEach(flattenItem => {
const { data } = flattenItem;
optionMap.set(data.value, data);
});

return values.map((val) => fillLegacyProps(optionMap.get(val)));
return values.map(val => fillLegacyProps(optionMap.get(val)));
}

export function isValueDisabled(value: RawValueType, options: CompatibleDataNode[]): boolean {
Expand Down Expand Up @@ -68,7 +68,7 @@ function getLevel({ parent }: FlattenNode): number {
export function flattenOptions(options: DataNode[]): FlattenDataNode[] {
// Add missing key
function fillKey(list: DataNode[]): TreeDataNode[] {
return (list || []).map((node) => {
return (list || []).map(node => {
const { value, key, children } = node;

const clone = {
Expand All @@ -88,7 +88,7 @@ export function flattenOptions(options: DataNode[]): FlattenDataNode[] {

const cacheMap = new Map<React.Key, FlattenDataNode>();
const flattenDateNodeList: (FlattenDataNode & { parentKey?: React.Key })[] = flattenList.map(
(node) => {
node => {
const { data } = node;
const { key } = data;

Expand All @@ -106,7 +106,7 @@ export function flattenOptions(options: DataNode[]): FlattenDataNode[] {
);

// Fill parent
flattenDateNodeList.forEach((flattenNode) => {
flattenDateNodeList.forEach(flattenNode => {
// eslint-disable-next-line no-param-reassign
flattenNode.parent = cacheMap.get(flattenNode.parentKey);
});
Expand Down Expand Up @@ -147,7 +147,7 @@ export function filterOptions(

function dig(list: DataNode[], keepAll: boolean = false) {
return list
.map((dataNode) => {
.map(dataNode => {
const { children } = dataNode;

const match = keepAll || filterOptionFunc(searchValue, fillLegacyProps(dataNode));
Expand All @@ -161,7 +161,7 @@ export function filterOptions(
}
return null;
})
.filter((node) => node);
.filter(node => node);
}

return dig(options);
Expand All @@ -175,20 +175,20 @@ export function getRawValueLabeled(
skipType?: SkipType,
ignoreDisabledCheck?: boolean,
) => FlattenDataNode,
getLabelProp: (node: DataNode) => React.ReactNode,
getLabelProp: (entity: FlattenDataNode) => React.ReactNode,
): LabelValueType[] {
const valueMap = new Map<RawValueType, LabelValueType>();

toArray(prevValue).forEach((item) => {
toArray(prevValue).forEach(item => {
if (item && typeof item === 'object' && 'value' in item) {
valueMap.set(item.value, item);
}
});

return values.map((val) => {
return values.map(val => {
const item: LabelValueType = { value: val };
const entity = getEntityByValue(val, 'select', true);
const label = entity ? getLabelProp(entity.data) : val;
const label = entity ? getLabelProp(entity) : val;

if (valueMap.has(val)) {
const labeledValue = valueMap.get(val);
Expand Down
34 changes: 34 additions & 0 deletions tests/Select.internal.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { mount } from 'enzyme';
import TreeSelect from '../src';

describe('TreeSelect.InternalAPI', () => {
it('labelRender', () => {
const wrapper = mount(
<TreeSelect
value="little"
treeData={[
{
label: 'Bamboo',
value: 'bamboo',
children: [
{ label: 'Light', value: 'light', children: [{ label: 'Little', value: 'little' }] },
],
},
]}
labelRender={entity => {
let current = entity;
const nodes = [];

while (current) {
nodes.unshift(current.data.label);
current = current.parent;
}

return nodes.join('>');
}}
/>,
);
expect(wrapper.find('.rc-tree-select-selection-item').text()).toEqual('Bamboo>Light>Little');
});
});