Commit 20c4d00d by Tobias Skarhed Committed by GitHub

Cascader: Add enable custom value (#21812)

* Add an early exit

* Fix issue with blur and only display label

* Remove unused code

* Enabled custom value

* Update test

* Add custom value creating according to #21869
parent 3617e595
...@@ -47,3 +47,7 @@ export const simple = () => ( ...@@ -47,3 +47,7 @@ export const simple = () => (
export const withInitialValue = () => ( export const withInitialValue = () => (
<Cascader options={options} initialValue="3" onSelect={val => console.log(val)} /> <Cascader options={options} initialValue="3" onSelect={val => console.log(val)} />
); );
export const withCustomValue = () => (
<Cascader options={options} allowCustomValue initialValue="Custom Initial Value" onSelect={val => console.log(val)} />
);
...@@ -29,18 +29,22 @@ const options = [ ...@@ -29,18 +29,22 @@ const options = [
const flatOptions = [ const flatOptions = [
{ {
singleLabel: 'Second',
label: 'First / Second', label: 'First / Second',
value: ['1', '2'], value: ['1', '2'],
}, },
{ {
singleLabel: 'Third',
label: 'First / Third', label: 'First / Third',
value: ['1', '3'], value: ['1', '3'],
}, },
{ {
singleLabel: 'Fourth',
label: 'First / Fourth', label: 'First / Fourth',
value: ['1', '4'], value: ['1', '4'],
}, },
{ {
singleLabel: 'FirstFirst',
label: 'FirstFirst', label: 'FirstFirst',
value: ['5'], value: ['5'],
}, },
......
...@@ -15,6 +15,7 @@ interface CascaderProps { ...@@ -15,6 +15,7 @@ interface CascaderProps {
onSelect(val: string): void; onSelect(val: string): void;
size?: FormInputSize; size?: FormInputSize;
initialValue?: string; initialValue?: string;
allowCustomValue?: boolean;
} }
interface CascaderState { interface CascaderState {
...@@ -64,6 +65,7 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState> ...@@ -64,6 +65,7 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState>
cpy.push(option); cpy.push(option);
if (!option.items) { if (!option.items) {
selectOptions.push({ selectOptions.push({
singleLabel: cpy[cpy.length - 1].label,
label: cpy.map(o => o.label).join(this.props.separator || ' / '), label: cpy.map(o => o.label).join(this.props.separator || ' / '),
value: cpy.map(o => o.value), value: cpy.map(o => o.value),
}); });
...@@ -84,10 +86,13 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState> ...@@ -84,10 +86,13 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState>
if (optionPath.indexOf(initValue) === optionPath.length - 1) { if (optionPath.indexOf(initValue) === optionPath.length - 1) {
return { return {
rcValue: optionPath, rcValue: optionPath,
activeLabel: option.label || '', activeLabel: option.singleLabel || '',
}; };
} }
} }
if (this.props.allowCustomValue) {
return { rcValue: [], activeLabel: initValue };
}
return { rcValue: [], activeLabel: '' }; return { rcValue: [], activeLabel: '' };
} }
...@@ -95,7 +100,7 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState> ...@@ -95,7 +100,7 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState>
onChange = (value: string[], selectedOptions: CascaderOption[]) => { onChange = (value: string[], selectedOptions: CascaderOption[]) => {
this.setState({ this.setState({
rcValue: value, rcValue: value,
activeLabel: selectedOptions.map(o => o.label).join(this.props.separator || ' / '), activeLabel: selectedOptions[selectedOptions.length - 1].label,
}); });
this.props.onSelect(selectedOptions[selectedOptions.length - 1].value); this.props.onSelect(selectedOptions[selectedOptions.length - 1].value);
...@@ -103,12 +108,22 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState> ...@@ -103,12 +108,22 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState>
//For select //For select
onSelect = (obj: SelectableValue<string[]>) => { onSelect = (obj: SelectableValue<string[]>) => {
const valueArray = obj.value || [];
this.setState({
activeLabel: obj.singleLabel || '',
rcValue: valueArray,
isSearching: false,
});
this.props.onSelect(valueArray[valueArray.length - 1]);
};
onCreateOption = (value: string) => {
this.setState({ this.setState({
activeLabel: obj.label || '', activeLabel: value,
rcValue: obj.value || [], rcValue: [],
isSearching: false, isSearching: false,
}); });
this.props.onSelect(this.state.rcValue[this.state.rcValue.length - 1]); this.props.onSelect(value);
}; };
onClick = () => { onClick = () => {
...@@ -138,47 +153,36 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState> ...@@ -138,47 +153,36 @@ export class Cascader extends React.PureComponent<CascaderProps, CascaderState>
onInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { onInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if ( if (
e.key !== 'ArrowDown' && e.key === 'ArrowDown' ||
e.key !== 'ArrowUp' && e.key === 'ArrowUp' ||
e.key !== 'Enter' && e.key === 'Enter' ||
e.key !== 'ArrowLeft' && e.key === 'ArrowLeft' ||
e.key !== 'ArrowRight' e.key === 'ArrowRight'
) { ) {
this.setState({ return;
focusCascade: false,
isSearching: true,
});
if (e.key === 'Backspace') {
const label = this.state.activeLabel || '';
this.setState({
activeLabel: label.slice(0, -1),
});
}
} }
};
onInputChange = (value: string) => {
this.setState({ this.setState({
activeLabel: value, focusCascade: false,
isSearching: true,
}); });
}; };
render() { render() {
const { size } = this.props; const { size, allowCustomValue } = this.props;
const { focusCascade, isSearching, searchableOptions, rcValue, activeLabel } = this.state; const { focusCascade, isSearching, searchableOptions, rcValue, activeLabel } = this.state;
return ( return (
<div> <div>
{isSearching ? ( {isSearching ? (
<Select <Select
inputValue={activeLabel} allowCustomValue={allowCustomValue}
placeholder="Search" placeholder="Search"
autoFocus={!focusCascade} autoFocus={!focusCascade}
onChange={this.onSelect} onChange={this.onSelect}
onInputChange={this.onInputChange}
onBlur={this.onBlur} onBlur={this.onBlur}
options={searchableOptions} options={searchableOptions}
size={size || 'md'} size={size || 'md'}
onCreateOption={this.onCreateOption}
/> />
) : ( ) : (
<RCCascader <RCCascader
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment