diff --git a/src/App.tsx b/src/App.tsx index 92b96eb..72d8bc8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,12 +1,15 @@ import React from 'react'; import './App.css'; import { Button, createMuiTheme, ThemeProvider } from '@material-ui/core'; -import { ApplicationDialogsProvider, matAlert, matConfirm } from './ui/widgets/DialogsProvider'; +import { ApplicationDialogsProvider, input, matAlert, matConfirm } from './ui/widgets/DialogsProvider'; +import { lightBlue, pink } from '@material-ui/core/colors'; function App() { const darkTheme = createMuiTheme({ palette: { type: 'dark', + primary: lightBlue, + secondary: pink, }, }); @@ -20,6 +23,13 @@ function App() { + ); diff --git a/src/ui/widgets/DialogsProvider.tsx b/src/ui/widgets/DialogsProvider.tsx index 7caadc6..188d5f8 100644 --- a/src/ui/widgets/DialogsProvider.tsx +++ b/src/ui/widgets/DialogsProvider.tsx @@ -4,11 +4,20 @@ * @author Pierre Hubert */ -import { Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button } from "@material-ui/core"; +import { Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button, TextField } from "@material-ui/core"; import React from "react"; let cache : ApplicationDialogsProvider; +export interface TextInputOptions { + title ?: string, + message ?: string, + initialValue ?: string, + minLength ?: number, + maxLength ?: number, + label : string, +} + interface AppDiagProvState { // Alert dialog @@ -20,11 +29,19 @@ interface AppDiagProvState { showConfirm: boolean, resolveConfirm ?: (confirmed: boolean) => void, + // Text input dialog + showInputDialog: boolean, + inputValue: string, + inputOptions: TextInputOptions, + resolveInput ?: (text: string) => void, + } export class ApplicationDialogsProvider extends React.Component<{}, AppDiagProvState> { private acceptConfirm: () => void; private rejectConfirm: () => void; + private cancelInput: () => void; + private confirmInput: () => void; constructor(props: any) { super(props); @@ -35,15 +52,28 @@ export class ApplicationDialogsProvider extends React.Component<{}, AppDiagProvS alertMessage: "", showAlert: false, + // Confirm dialog showConfirm: false, confirmMessage: "", resolveConfirm: undefined, + + // Text input dialog + showInputDialog: false, + inputValue: "", + inputOptions: { + label: "" + }, + resolveInput: undefined, }; this.handleCloseAlert = this.handleCloseAlert.bind(this); this.acceptConfirm = this.handleCloseConfirm.bind(this, true); this.rejectConfirm = this.handleCloseConfirm.bind(this, false); + + this.handleInputValueChanged = this.handleInputValueChanged.bind(this); + this.cancelInput = this.handleCloseInput.bind(this, true); + this.confirmInput = this.handleCloseInput.bind(this, false); } showAlert(message: string) { @@ -75,6 +105,43 @@ export class ApplicationDialogsProvider extends React.Component<{}, AppDiagProvS this.state.resolveConfirm && this.state.resolveConfirm(accept); } + showInput(options: TextInputOptions) : Promise { + return new Promise((res, _rej) => { + this.setState({ + showInputDialog: true, + inputOptions: options, + resolveInput: res, + inputValue: options.initialValue || "" + }); + }); + } + + handleInputValueChanged(e: React.ChangeEvent){ + this.setState({inputValue: e.target.value}); + } + + handleCloseInput(cancel: boolean) { + this.setState({ + showInputDialog: false + }); + + if (!cancel) + this.state.resolveInput && this.state.resolveInput(this.state.inputValue); + } + + get isInputValid() : boolean { + const options = this.state.inputOptions; + const value = this.state.inputValue; + + if (options.minLength && value.length < options.minLength) + return false; + + if (options.maxLength && value.length > options.maxLength) + return false; + + return true; + } + render() { cache = this; @@ -125,6 +192,39 @@ export class ApplicationDialogsProvider extends React.Component<{}, AppDiagProvS + + {/* Text input dialog */} + + + {this.state.inputOptions.title || this.state.inputOptions.label} + + + {this.state.inputOptions.message ? + {this.state.inputOptions.message}

+
: } + + +
+ + + + +
) } } @@ -135,4 +235,8 @@ export function matAlert(msg: string) { export function matConfirm(msg: string) : Promise { return cache.showConfirm(msg); +} + +export function input(options: TextInputOptions) : Promise { + return cache.showInput(options); } \ No newline at end of file