parent
5900185d37
commit
796d1c245b
@ -0,0 +1,64 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { connect } from '../redux';
|
||||||
|
import { FieldBase } from './base';
|
||||||
|
import { FieldDropdown } from './dropdown';
|
||||||
|
import { FieldDropdownWithInput } from './dropdownwithinput';
|
||||||
|
import { FieldString } from './string';
|
||||||
|
|
||||||
|
// Maybe in the future we can make this generic, but we'd have to make FieldDropdown etc also generic first
|
||||||
|
type T = string;
|
||||||
|
|
||||||
|
// TODO: Allow reordering of items
|
||||||
|
|
||||||
|
export interface Props<T> {
|
||||||
|
options?: T[];
|
||||||
|
freeText?: boolean;
|
||||||
|
//displayName?(item: T): string;
|
||||||
|
displayStyle?(item: T): React.CSSProperties;
|
||||||
|
}
|
||||||
|
interface State {
|
||||||
|
open: boolean;
|
||||||
|
inputText: string;
|
||||||
|
}
|
||||||
|
export class FieldList extends FieldBase<T[] | undefined, Props<T>, State> {
|
||||||
|
public getInitialSubState(props: Props<string>): State {
|
||||||
|
return { open: false, inputText: '' };
|
||||||
|
}
|
||||||
|
protected renderNewInputField(): React.ReactNode {
|
||||||
|
const { inputText } = this.state;
|
||||||
|
const { freeText, options, displayStyle } = this.props;
|
||||||
|
const FD = options?.length ? (freeText ? FieldDropdownWithInput : FieldDropdown) : (freeText ? FieldString : undefined);
|
||||||
|
return FD && <FD value={inputText} values={options} displayStyle={displayStyle}
|
||||||
|
onChange={t => this.setState({ inputText: t || '' })} />;
|
||||||
|
}
|
||||||
|
public renderInput(): React.ReactNode {
|
||||||
|
const { newValue } = this.state;
|
||||||
|
const { displayStyle } = this.props;
|
||||||
|
const newInput = this.renderNewInputField();
|
||||||
|
return <div className="FieldList">
|
||||||
|
{newInput && <div className="adder">{newInput}<button onClick={this.onAdd}>+</button></div>}
|
||||||
|
{newValue?.map((item, index) => <li key={index} style={displayStyle?.(item)}>
|
||||||
|
<p>{item}</p>
|
||||||
|
<button onClick={this.onRemove.bind(this, index)}>x</button>
|
||||||
|
</li>)}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
protected onAdd = () => {
|
||||||
|
const inputText = this.state.inputText?.trim();
|
||||||
|
if (!inputText) return;
|
||||||
|
this.setState({
|
||||||
|
inputText: '',
|
||||||
|
newValue: [...this.state.newValue || [], inputText]
|
||||||
|
}, () => this.props.onChange(this.state.newValue));
|
||||||
|
};
|
||||||
|
protected onRemove = (index: number) => {
|
||||||
|
const newValue = [...this.state.newValue || []];
|
||||||
|
newValue.splice(index, 1);
|
||||||
|
this.setState({ newValue }, () => this.props.onChange(newValue));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FieldConfigListState = { options: string[] };
|
||||||
|
export const FieldConfigList = connect(FieldList)<FieldConfigListState>(
|
||||||
|
state => ({ options: state.data.configs.map(c => c.name).sort() }),
|
||||||
|
);
|
Loading…
Reference in new issue