1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
6 import { Chips } from '~/components/chips/chips';
7 import { Input } from '@material-ui/core';
9 interface ChipsInputProps<Value> {
11 getLabel?: (value: Value) => string;
12 onChange: (value: Value[]) => void;
13 createNewValue: (value: string) => Value;
16 export class ChipsInput<Value> extends React.Component<ChipsInputProps<Value>> {
22 filler = React.createRef<HTMLDivElement>();
25 setText = (event: React.ChangeEvent<HTMLInputElement>) => {
26 this.setState({ text: event.target.value });
29 handleKeyPress = ({ key }: React.KeyboardEvent<HTMLInputElement>) => {
30 if (key === 'Enter') {
31 this.createNewValue();
32 } else if (key === 'Backspace') {
33 this.deleteLastValue();
37 createNewValue = () => {
38 if (this.state.text) {
39 const newValue = this.props.createNewValue(this.state.text);
40 this.setState({ text: '' });
41 this.props.onChange([...this.props.values, newValue]);
45 deleteLastValue = () => {
46 if (this.state.text.length === 0 && this.props.values.length > 0) {
47 this.props.onChange(this.props.values.slice(0, -1));
51 updateStyles = () => {
53 clearTimeout(this.timeout);
55 this.timeout = setTimeout(() => this.forceUpdate());
61 <div style={{ minHeight: '40px', zIndex: 1, position: 'relative' }}>
62 <Chips {...this.props} filler={<div ref={this.filler} />} />
65 value={this.state.text}
66 onChange={this.setText}
67 onKeyDown={this.handleKeyPress}
68 style={{ top: '-24px' }}
69 inputProps={{ style: this.getInputStyles(), }}
74 getInputStyles = (): React.CSSProperties => ({
75 width: this.filler.current
76 ? this.filler.current.offsetWidth + 8
79 right: this.filler.current
80 ? `calc(${this.filler.current.offsetWidth}px - 100%)`