Files
ThreadNet-Web/src/components/views/dialogs/TextInputDialog.tsx
T

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

140 lines
4.4 KiB
TypeScript
Raw Normal View History

2016-01-13 16:32:41 +01:00
/*
2024-09-09 14:57:16 +01:00
Copyright 2024 New Vector Ltd.
2016-01-13 16:32:41 +01:00
Copyright 2015, 2016 OpenMarket Ltd
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
2024-09-09 14:57:16 +01:00
Please see LICENSE files in the repository root for full details.
2016-01-13 16:32:41 +01:00
*/
2021-09-05 08:35:24 +02:00
import React, { ChangeEvent, createRef } from "react";
2021-10-22 17:23:32 -05:00
2020-03-13 17:32:02 +00:00
import Field from "../elements/Field";
import { _t, _td, TranslationKey } from "../../../languageHandler";
2021-09-05 08:35:24 +02:00
import { IFieldState, IValidationResult } from "../elements/Validation";
import BaseDialog from "./BaseDialog";
import DialogButtons from "../elements/DialogButtons";
interface IProps {
title: string;
description: React.ReactNode;
value: string;
2021-09-05 08:35:24 +02:00
placeholder?: string;
button?: string;
busyMessage: TranslationKey;
focus: boolean;
hasCancel: boolean;
2022-09-07 16:42:39 +01:00
validator?: (fieldState: IFieldState) => Promise<IValidationResult>; // result of withValidation
2021-09-05 08:35:24 +02:00
fixedWidth?: boolean;
onFinished(ok?: false, text?: void): void;
onFinished(ok: true, text: string): void;
2021-09-05 08:35:24 +02:00
}
interface IState {
value: string;
busy: boolean;
valid: boolean;
}
2016-01-13 16:32:41 +01:00
2021-09-05 08:35:24 +02:00
export default class TextInputDialog extends React.Component<IProps, IState> {
private field = createRef<Field>();
2016-01-13 16:32:41 +01:00
public static defaultProps: Partial<IProps> = {
2020-08-29 12:14:16 +01:00
title: "",
value: "",
description: "",
busyMessage: _td("common|loading"),
2020-08-29 12:14:16 +01:00
focus: true,
hasCancel: true,
};
public constructor(props: IProps) {
2020-08-29 12:14:16 +01:00
super(props);
this.state = {
2020-03-13 17:32:02 +00:00
value: this.props.value,
busy: false,
2020-03-13 17:32:02 +00:00
valid: false,
};
2020-08-29 12:14:16 +01:00
}
2020-03-13 17:32:02 +00:00
2021-09-05 08:35:24 +02:00
public componentDidMount(): void {
2016-01-13 16:32:41 +01:00
if (this.props.focus) {
// Set the cursor at the end of the text input
2020-03-13 17:32:02 +00:00
// this._field.current.value = this.props.value;
this.field.current?.focus();
2016-01-13 16:32:41 +01:00
}
2020-08-29 12:14:16 +01:00
}
2016-01-13 16:32:41 +01:00
2021-09-05 08:35:24 +02:00
private onOk = async (ev: React.FormEvent): Promise<void> => {
2020-03-13 17:32:02 +00:00
ev.preventDefault();
if (!this.field.current) return;
2020-03-13 17:32:02 +00:00
if (this.props.validator) {
this.setState({ busy: true });
2021-09-05 08:35:24 +02:00
await this.field.current.validate({ allowEmpty: false });
2020-03-13 17:32:02 +00:00
2021-09-05 08:35:24 +02:00
if (!this.field.current.state.valid) {
this.field.current.focus();
this.field.current.validate({ allowEmpty: false, focused: true });
this.setState({ busy: false });
2020-03-13 17:32:02 +00:00
return;
}
}
this.props.onFinished(true, this.state.value);
2020-08-29 12:14:16 +01:00
};
2016-01-13 16:32:41 +01:00
2021-09-05 08:35:24 +02:00
private onCancel = (): void => {
2016-01-13 16:32:41 +01:00
this.props.onFinished(false);
2020-08-29 12:14:16 +01:00
};
2016-01-13 16:32:41 +01:00
2021-09-05 08:35:24 +02:00
private onChange = (ev: ChangeEvent<HTMLInputElement>): void => {
2020-03-13 17:32:02 +00:00
this.setState({
value: ev.target.value,
});
2020-08-29 12:14:16 +01:00
};
2020-03-13 17:32:02 +00:00
2021-09-05 08:35:24 +02:00
private onValidate = async (fieldState: IFieldState): Promise<IValidationResult> => {
const result = await this.props.validator!(fieldState);
2020-03-13 17:32:02 +00:00
this.setState({
valid: !!result.valid,
2020-03-13 17:32:02 +00:00
});
return result;
2020-08-29 12:14:16 +01:00
};
2020-03-13 17:32:02 +00:00
public render(): React.ReactNode {
2016-01-13 16:32:41 +01:00
return (
2020-03-16 12:00:56 +00:00
<BaseDialog
className="mx_TextInputDialog"
onFinished={this.props.onFinished}
2017-01-24 15:54:05 +00:00
title={this.props.title}
2020-03-16 12:00:56 +00:00
fixedWidth={this.props.fixedWidth}
2017-01-24 15:54:05 +00:00
>
<form onSubmit={this.onOk}>
<div className="mx_Dialog_content">
<div className="mx_TextInputDialog_label">
<label htmlFor="textinput"> {this.props.description} </label>
</div>
<div>
2020-03-13 17:32:02 +00:00
<Field
2019-12-08 12:16:17 +00:00
className="mx_TextInputDialog_input"
2021-09-05 08:35:24 +02:00
ref={this.field}
2020-03-13 17:32:02 +00:00
type="text"
label={this.props.placeholder}
value={this.state.value}
onChange={this.onChange}
onValidate={this.props.validator ? this.onValidate : undefined}
/>
</div>
2016-01-13 16:32:41 +01:00
</div>
</form>
<DialogButtons
primaryButton={this.state.busy ? _t(this.props.busyMessage) : this.props.button}
disabled={this.state.busy}
2017-12-23 16:50:35 +13:00
onPrimaryButtonClick={this.onOk}
onCancel={this.onCancel}
hasCancel={this.props.hasCancel}
/>
2017-01-24 15:54:05 +00:00
</BaseDialog>
2016-01-13 16:32:41 +01:00
);
2020-08-29 12:14:16 +01:00
}
}