Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: mount scrollTo on ref #298

Merged
merged 15 commits into from
Dec 28, 2020
Merged
18 changes: 4 additions & 14 deletions examples/basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,7 @@ class Demo extends React.Component {
return true;
};

filterTreeNode = (input, child) =>
String(child.props.title).indexOf(input) === 0;
filterTreeNode = (input, child) => String(child.props.title).indexOf(input) === 0;

render() {
const {
Expand All @@ -152,11 +151,7 @@ class Demo extends React.Component {
return (
<div style={{ margin: 20 }}>
<h2>tree-select in dialog</h2>
<button
type="button"
className="btn btn-primary"
onClick={this.onClick}
>
<button type="button" className="btn btn-primary" onClick={this.onClick}>
show dialog
</button>
{visible ? (
Expand Down Expand Up @@ -280,7 +275,7 @@ class Demo extends React.Component {
showCheckedStrategy={SHOW_PARENT}
onChange={this.onChange}
onSelect={this.onSelect}
maxTagCount={2}
maxTagCount="responsive"
maxTagPlaceholder={valueList => {
console.log('Max Tag Rest Value:', valueList);
return `${valueList.length} rest...`;
Expand Down Expand Up @@ -368,12 +363,7 @@ class Demo extends React.Component {
<TreeNode value="" title="parent 1" key="">
<TreeNode value="parent 1-0" title="parent 1-0" key="0-1-0">
<TreeNode value="leaf1" title="my leaf" key="random" />
<TreeNode
value="leaf2"
title="your leaf"
key="random1"
disabled
/>
<TreeNode value="leaf2" title="your leaf" key="random1" disabled />
</TreeNode>
<TreeNode value="parent 1-1" title="parent 1-1" key="0-1-1">
<TreeNode
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rc-tree-select",
"version": "4.1.2",
"version": "4.3.0",
"description": "tree-select ui component for react",
"keywords": [
"react",
Expand Down Expand Up @@ -66,8 +66,8 @@
"dependencies": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"rc-select": "^11.1.1",
"rc-tree": "^3.8.0",
"rc-select": "^12.0.0",
"rc-tree": "^4.0.0",
"rc-util": "^5.0.5"
}
}
17 changes: 11 additions & 6 deletions src/OptionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import KeyCode from 'rc-util/lib/KeyCode';
import useMemo from 'rc-util/lib/hooks/useMemo';
import { RefOptionListProps } from 'rc-select/lib/OptionList';
import Tree, { TreeProps } from 'rc-tree';
import { EventDataNode } from 'rc-tree/lib/interface';
import { EventDataNode, ScrollTo } from 'rc-tree/lib/interface';
import { FlattenDataNode, RawValueType, DataNode, TreeDataNode, Key } from './interface';
import { SelectContext } from './Context';
import useKeyValueMapping from './hooks/useKeyValueMapping';
Expand Down Expand Up @@ -52,10 +52,12 @@ export interface OptionListProps<OptionsType extends object[]> {
onMouseEnter: () => void;
}

const OptionList: React.RefForwardingComponent<RefOptionListProps, OptionListProps<DataNode[]>> = (
props,
ref,
) => {
type ReviseRefOptionListProps = Omit<RefOptionListProps, 'scrollTo'> & { scrollTo: ScrollTo };

const OptionList: React.RefForwardingComponent<
ReviseRefOptionListProps,
OptionListProps<DataNode[]>
> = (props, ref) => {
const {
prefixCls,
height,
Expand Down Expand Up @@ -190,6 +192,7 @@ const OptionList: React.RefForwardingComponent<RefOptionListProps, OptionListPro
const activeEntity = getEntityByKey(activeKey);

React.useImperativeHandle(ref, () => ({
scrollTo: treeRef.current?.scrollTo,
onKeyDown: event => {
const { which } = event;
switch (which) {
Expand Down Expand Up @@ -280,7 +283,9 @@ const OptionList: React.RefForwardingComponent<RefOptionListProps, OptionListPro
);
};

const RefOptionList = React.forwardRef<RefOptionListProps, OptionListProps<DataNode[]>>(OptionList);
const RefOptionList = React.forwardRef<ReviseRefOptionListProps, OptionListProps<DataNode[]>>(
OptionList,
);
RefOptionList.displayName = 'OptionList';

export default RefOptionList;
3 changes: 1 addition & 2 deletions src/TreeSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ export interface TreeSelectProps<ValueType = DefaultValueType>
searchValue?: string;
autoClearSearchValue?: boolean;

maxTagTextLength?: number;
maxTagCount?: number;
maxTagPlaceholder?: (omittedValues: LabelValueType[]) => React.ReactNode;

loadData?: (dataNode: LegacyDataNode) => Promise<unknown>;
Expand Down Expand Up @@ -202,6 +200,7 @@ const RefTreeSelect = React.forwardRef<RefSelectProps, TreeSelectProps>((props,
const selectRef = React.useRef<RefSelectProps>(null);

React.useImperativeHandle(ref, () => ({
scrollTo: selectRef.current.scrollTo,
focus: selectRef.current.focus,
blur: selectRef.current.blur,
}));
Expand Down
6 changes: 4 additions & 2 deletions src/utils/valueUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ import {
import { fillLegacyProps } from './legacyUtil';
import { SkipType } from '../hooks/useKeyValueMapping';

type CompatibleDataNode = Omit<FlattenDataNode, 'level'>;

export function toArray<T>(value: T | T[]): T[] {
if (Array.isArray(value)) {
return value;
}
return value !== undefined ? [value] : [];
}

export function findValueOption(values: RawValueType[], options: FlattenDataNode[]): DataNode[] {
export function findValueOption(values: RawValueType[], options: CompatibleDataNode[]): DataNode[] {
const optionMap: Map<RawValueType, DataNode> = new Map();

options.forEach(flattenItem => {
Expand All @@ -31,7 +33,7 @@ export function findValueOption(values: RawValueType[], options: FlattenDataNode
return values.map(val => fillLegacyProps(optionMap.get(val)));
}

export function isValueDisabled(value: RawValueType, options: FlattenDataNode[]): boolean {
export function isValueDisabled(value: RawValueType, options: CompatibleDataNode[]): boolean {
const option = findValueOption([value], options)[0];
if (option) {
return option.disabled;
Expand Down
48 changes: 13 additions & 35 deletions tests/Select.checkable.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,7 @@ describe('TreeSelect.checkable', () => {
onChange={this.handleChange}
disabled={disabled}
/>
<input
type="checkbox"
onChange={e => this.switch(e.target.checked)}
id="checkbox"
/>{' '}
<input type="checkbox" onChange={e => this.switch(e.target.checked)} id="checkbox" />{' '}
禁用
</div>
);
Expand Down Expand Up @@ -335,9 +331,7 @@ describe('TreeSelect.checkable', () => {
],
},
];
const wrapper = mount(
<TreeSelect treeCheckable treeData={treeData} open />,
);
const wrapper = mount(<TreeSelect treeCheckable treeData={treeData} open />);
wrapper.search('58');
wrapper.selectNode(2);
expect(wrapper.getSelection()).toHaveLength(1);
Expand Down Expand Up @@ -402,11 +396,7 @@ describe('TreeSelect.checkable', () => {

wrapper.search('0-0');
wrapper.selectNode(0);
expect(onChange).toHaveBeenCalledWith(
['0-1-0', '0-1-2'],
expect.anything(),
expect.anything(),
);
expect(onChange).toHaveBeenCalledWith(['0-1-0', '0-1-2'], expect.anything(), expect.anything());
});

// https://github.com/ant-design/ant-design/issues/13328
Expand Down Expand Up @@ -443,11 +433,7 @@ describe('TreeSelect.checkable', () => {

wrapper.search('0-0-1');
wrapper.selectNode(1);
expect(onChange).toHaveBeenCalledWith(
['0-0-1'],
expect.anything(),
expect.anything(),
);
expect(onChange).toHaveBeenCalledWith(['0-0-1'], expect.anything(), expect.anything());

expect(
wrapper
Expand Down Expand Up @@ -615,14 +601,10 @@ describe('TreeSelect.checkable', () => {
},
];

const wrapper = mount(
<TreeSelect defaultValue={['0-0']} treeData={treeData} treeCheckable />,
);
const wrapper = mount(<TreeSelect defaultValue={['0-0']} treeData={treeData} treeCheckable />);

expect(wrapper.getSelection().length).toBeTruthy();
expect(
wrapper.find('.rc-tree-select-selection-item-remove').length,
).toBeFalsy();
expect(wrapper.find('.rc-tree-select-selection-item-remove').length).toBeFalsy();
});

it('treeCheckStrictly can set halfChecked', () => {
Expand All @@ -634,26 +616,22 @@ describe('TreeSelect.checkable', () => {
value={[{ value: 'half', halfChecked: true }]}
open
onChange={onChange}
treeData={[
{ value: 'half', title: 'Half Check' },
{ value: 'full', title: 'Full Check' },
]}
treeData={[{ value: 'half', title: 'Half Check' }, { value: 'full', title: 'Full Check' }]}
/>,
);

function getTreeNode(index) {
return wrapper.find('.rc-tree-select-tree-treenode').at(index);
return wrapper
.find('.rc-tree-select-tree-treenode')
.not('[aria-hidden]')
.at(index);
}

expect(
getTreeNode(0).hasClass(
'rc-tree-select-tree-treenode-checkbox-indeterminate',
),
getTreeNode(0).hasClass('rc-tree-select-tree-treenode-checkbox-indeterminate'),
).toBeTruthy();
expect(
getTreeNode(1).hasClass(
'rc-tree-select-tree-treenode-checkbox-indeterminate',
),
getTreeNode(1).hasClass('rc-tree-select-tree-treenode-checkbox-indeterminate'),
).toBeFalsy();

wrapper.selectNode(1);
Expand Down
1 change: 1 addition & 0 deletions tests/Select.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ describe('TreeSelect.basic', () => {
expect(
wrapper
.find('.rc-tree-select-tree-treenode')
.not('[aria-hidden]')
.at(1)
.hasClass('rc-tree-select-tree-treenode-switcher-open'),
).toBeTruthy();
Expand Down
Loading