Files
ThreadNet-Web/src/components/views/elements/EditableItemList.tsx
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

169 lines
5.1 KiB
TypeScript
Raw Normal View History

/*
2024-09-09 14:57:16 +01:00
Copyright 2024 New Vector Ltd.
Copyright 2017-2021 The Matrix.org Foundation C.I.C.
2024-09-09 14:57:16 +01:00
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
2023-02-13 11:39:16 +00:00
import React, { ChangeEvent } from "react";
import { _t } from "../../../languageHandler";
2019-02-08 09:11:30 -07:00
import Field from "./Field";
2023-02-13 11:39:16 +00:00
import AccessibleButton, { ButtonEvent } from "./AccessibleButton";
interface IItemProps {
index: number;
value?: string;
onRemove?(index: number): void;
}
interface IItemState {
verifyRemove: boolean;
}
export class EditableItem extends React.Component<IItemProps, IItemState> {
public state = {
verifyRemove: false,
2019-02-08 09:11:30 -07:00
};
2023-02-13 11:39:16 +00:00
private onRemove = (e: ButtonEvent): void => {
2019-02-08 09:11:30 -07:00
e.stopPropagation();
e.preventDefault();
this.setState({ verifyRemove: true });
2019-02-08 09:11:30 -07:00
};
2023-02-13 11:39:16 +00:00
private onDontRemove = (e: ButtonEvent): void => {
2019-02-08 09:11:30 -07:00
e.stopPropagation();
e.preventDefault();
this.setState({ verifyRemove: false });
2019-02-08 09:11:30 -07:00
};
2023-02-13 11:39:16 +00:00
private onActuallyRemove = (e: ButtonEvent): void => {
2019-02-08 09:11:30 -07:00
e.stopPropagation();
e.preventDefault();
if (this.props.onRemove) this.props.onRemove(this.props.index);
this.setState({ verifyRemove: false });
2019-02-08 09:11:30 -07:00
};
public render(): React.ReactNode {
if (this.state.verifyRemove) {
return (
<div className="mx_EditableItem">
<span className="mx_EditableItem_promptText">{_t("common|are_you_sure")}</span>
2021-04-27 17:23:27 +02:00
<AccessibleButton
onClick={this.onActuallyRemove}
2021-04-27 17:23:27 +02:00
kind="primary_sm"
className="mx_EditableItem_confirmBtn"
>
{_t("action|yes")}
</AccessibleButton>
2021-04-27 17:23:27 +02:00
<AccessibleButton
onClick={this.onDontRemove}
2021-04-27 17:23:27 +02:00
kind="danger_sm"
className="mx_EditableItem_confirmBtn"
>
{_t("action|no")}
</AccessibleButton>
</div>
);
}
2019-02-08 09:11:30 -07:00
return (
<div className="mx_EditableItem">
<div
onClick={this.onRemove}
className="mx_EditableItem_delete"
title={_t("action|remove")}
role="button"
/>
<span className="mx_EditableItem_item">{this.props.value}</span>
2019-02-08 09:11:30 -07:00
</div>
);
}
}
interface IProps {
id: string;
items: string[];
itemsLabel?: string;
noItemsLabel?: string;
placeholder?: string;
newItem?: string;
canEdit?: boolean;
canRemove?: boolean;
suggestionsListId?: string;
onItemAdded?(item?: string): void;
onItemRemoved?(index: number): void;
onNewItemChanged?(item: string): void;
}
export default class EditableItemList<P = {}> extends React.PureComponent<IProps & P> {
2023-02-13 11:39:16 +00:00
protected onItemAdded = (e: ButtonEvent): void => {
2019-02-08 09:11:30 -07:00
e.stopPropagation();
e.preventDefault();
2023-02-13 11:39:16 +00:00
this.props.onItemAdded?.(this.props.newItem);
2019-02-08 09:11:30 -07:00
};
protected onItemRemoved = (index: number): void => {
2023-02-13 11:39:16 +00:00
this.props.onItemRemoved?.(index);
2019-02-08 09:11:30 -07:00
};
2023-02-13 11:39:16 +00:00
protected onNewItemChanged = (e: ChangeEvent<HTMLInputElement>): void => {
this.props.onNewItemChanged?.(e.target.value);
2019-02-20 16:13:35 -07:00
};
protected renderNewItemField(): JSX.Element {
2019-02-08 09:11:30 -07:00
return (
2021-04-29 19:57:02 +02:00
<form
onSubmit={this.onItemAdded}
2021-04-29 19:57:02 +02:00
autoComplete="off"
noValidate={true}
className="mx_EditableItemList_newItem"
>
<Field
label={this.props.placeholder}
type="text"
autoComplete="off"
value={this.props.newItem || ""}
onChange={this.onNewItemChanged}
list={this.props.suggestionsListId}
/>
<AccessibleButton
onClick={this.onItemAdded}
kind="primary"
type="submit"
disabled={!this.props.newItem}
>
{_t("action|add")}
</AccessibleButton>
2019-02-08 09:11:30 -07:00
</form>
2019-02-21 17:53:29 -07:00
);
2019-02-08 09:11:30 -07:00
}
public render(): React.ReactNode {
const editableItems = this.props.items.map((item, index) => {
if (!this.props.canRemove) {
return <li key={item}>{item}</li>;
}
return <EditableItem key={item} index={index} value={item} onRemove={this.onItemRemoved} />;
});
const editableItemsSection = this.props.canRemove ? editableItems : <ul>{editableItems}</ul>;
2019-02-08 09:11:30 -07:00
const label = this.props.items.length > 0 ? this.props.itemsLabel : this.props.noItemsLabel;
return (
<div className="mx_EditableItemList" id={this.props.id}>
<div className="mx_EditableItemList_label">{label}</div>
{editableItemsSection}
{this.props.canEdit ? this.renderNewItemField() : <div />}
</div>
);
2019-02-08 09:11:30 -07:00
}
}