/* tslint:disable:max-line-length */
"use strict";
import React, { Component } from "react";
import EditableListItem from "./EditableListItem";
const _ = browser.i18n.getMessage;
interface EditableListProps {
data: string[];
itemPattern: RegExp;
onChange (data: string[]): void;
itemPatternError (err?: string): string;
}
interface EditableListState {
addingNewItem: boolean;
rawView: boolean;
rawViewValue: string;
}
export default class EditableList extends Component<
EditableListProps, EditableListState> {
private rawViewTextArea: (HTMLTextAreaElement | null) = null;
constructor (props: EditableListProps) {
super(props);
this.state = {
addingNewItem: false
, rawView: false
, rawViewValue: ""
};
this.handleItemRemove = this.handleItemRemove.bind(this);
this.handleItemEdit = this.handleItemEdit.bind(this);
this.handleSwitchView = this.handleSwitchView.bind(this);
this.handleSaveRaw = this.handleSaveRaw.bind(this);
this.handleRawViewTextAreaChange = this.handleRawViewTextAreaChange.bind(this);
this.handleAddItem = this.handleAddItem.bind(this);
this.handleNewItemRemove = this.handleNewItemRemove.bind(this);
this.handleNewItemEdit = this.handleNewItemEdit.bind(this);
}
public render () {
return (
{ this.state.rawView
? (
) : (
{ this.props.data.map((item, i) =>
)}
{ this.state.addingNewItem &&
}
)}
{ !this.state.rawView &&
}
{ this.state.rawView &&
}
);
}
private handleItemRemove (item: string) {
const newItems = new Set(this.props.data);
newItems.delete(item);
this.props.onChange([...newItems]);
}
private handleItemEdit (item: string, newValue: string) {
this.props.onChange(this.props.data.map(
currentItem => currentItem === item
? newValue
: currentItem));
}
private handleSwitchView () {
this.setState(currentState => {
if (currentState.rawView) {
return {
rawView: false
, rawViewValue: ""
};
}
return {
rawView: true
, rawViewValue: this.props.data.join("\n")
};
});
}
private handleSaveRaw () {
this.setState(currentState => {
const newItems = currentState.rawViewValue.split("\n")
.filter(item => item !== "");
if ("itemPattern" in this.props) {
for (const item of newItems) {
if (!this.props.itemPattern.test(item)) {
this.rawViewTextArea?.setCustomValidity(
this.props.itemPatternError(item));
return;
}
}
this.rawViewTextArea?.setCustomValidity("");
}
this.props.onChange(newItems);
});
}
private handleRawViewTextAreaChange (ev: React.ChangeEvent) {
if (!this.rawViewTextArea) {
return;
}
if (this.rawViewTextArea.scrollHeight > this.rawViewTextArea.clientHeight) {
this.rawViewTextArea.style.height = `${this.rawViewTextArea.scrollHeight}px`;
}
this.setState({
rawViewValue: ev.target.value
});
}
private handleAddItem () {
this.setState({
addingNewItem: true
});
}
private handleNewItemRemove () {
this.setState({
addingNewItem: false
});
}
private handleNewItemEdit (_item: string, newItem: string) {
this.setState({
addingNewItem: false
}, () => {
this.props.onChange([ ...this.props.data, newItem ]);
});
}
}