添加 prompt 方法

This commit is contained in:
2betop 2020-06-29 17:35:22 +08:00
parent 8f60b75e28
commit ac80d3d4d3
2 changed files with 132 additions and 26 deletions

View File

@ -9,6 +9,9 @@ import Modal from './Modal';
import Button from './Button';
import {ClassNamesFn, themeable, ThemeProps} from '../theme';
import {LocaleProps, localeable} from '../locale';
import Html from './Html';
import {PlainObject} from '../types';
import {render as renderSchema} from '../factory';
export interface AlertProps extends ThemeProps, LocaleProps {
container?: any;
@ -24,6 +27,9 @@ export interface AlertState {
title?: string;
content: string;
confirm: boolean;
prompt?: boolean;
controls?: any;
value?: any;
confirmText?: string;
}
@ -57,7 +63,8 @@ export class Alert extends React.Component<AlertProps, AlertState> {
this.handleConfirm = this.handleConfirm.bind(this);
this.handleCancel = this.handleCancel.bind(this);
this.modalRef = this.modalRef.bind(this);
this.bodyRef = this.bodyRef.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.scopeRef = this.scopeRef.bind(this);
}
static defaultProps = {
@ -86,8 +93,19 @@ export class Alert extends React.Component<AlertProps, AlertState> {
Alert.instance = null;
}
schemaSope: any;
scopeRef(schemaSope: any) {
this.schemaSope = schemaSope;
}
handleConfirm() {
this.close(true);
const form = this.schemaSope?.getComponentByName('form');
if (form) {
form.doAction({type: 'submit'});
} else {
this.close(true);
}
}
handleCancel() {
@ -95,7 +113,7 @@ export class Alert extends React.Component<AlertProps, AlertState> {
}
close(confirmed: boolean) {
const isConfirm = this.state.confirm;
const isConfirm = this.state.confirm || this.state.prompt;
this.setState(
{
@ -128,13 +146,51 @@ export class Alert extends React.Component<AlertProps, AlertState> {
});
}
prompt(
controls: any,
defaultValue?: any,
title: string = '请输入',
confirmText: string = '确认'
) {
if (typeof controls === 'string') {
// 兼容浏览器标准用法。
controls = [
{
name: 'text',
label: controls,
type: 'text'
}
];
if (typeof defaultValue === 'string') {
defaultValue = {
text: defaultValue
};
}
} else if (!Array.isArray(controls)) {
controls = [controls];
}
this.setState({
title,
controls,
show: true,
prompt: true,
value: defaultValue,
confirmText
});
return new Promise(resolve => {
this._resolve = resolve;
});
}
modalRef(ref: any) {
this._modal = ref;
}
bodyRef(ref: any) {
this._body = ref;
this._body && (this._body.innerHTML = this.state.content);
handleFormSubmit(values: any) {
this.close(values);
}
render() {
@ -145,10 +201,11 @@ export class Alert extends React.Component<AlertProps, AlertState> {
title,
confirmBtnLevel,
alertBtnLevel,
classnames: cx,
classPrefix
classnames: cx
} = this.props;
const __ = this.props.translate;
const finalTitle = __(this.state.title ?? title);
const finalConfirmText = __(this.state.confirmText ?? confirmText);
return (
<Modal
@ -156,31 +213,72 @@ export class Alert extends React.Component<AlertProps, AlertState> {
onHide={this.handleCancel}
container={container}
ref={this.modalRef}
closeOnEsc
>
<div className={cx('Modal-header')}>
<div className={cx('Modal-title')}>
{__(this.state.title || title)}
{finalTitle ? (
<div className={cx('Modal-header')}>
<div className={cx('Modal-title')}>{finalTitle}</div>
</div>
</div>
) : null}
<div className={cx('Modal-body')}>
<div ref={this.bodyRef} />
</div>
<div className={cx('Modal-footer')}>
{this.state.confirm ? (
<Button onClick={this.handleCancel}>{__(cancelText)}</Button>
) : null}
<Button
level={this.state.confirm ? confirmBtnLevel : alertBtnLevel}
onClick={this.handleConfirm}
>
{__(this.state.confirmText || confirmText)}
</Button>
{this.state.prompt ? (
renderForm(
this.state.controls,
this.state.value,
this.handleFormSubmit,
this.scopeRef
)
) : (
<Html html={this.state.content} />
)}
</div>
{finalConfirmText ? (
<div className={cx('Modal-footer')}>
{this.state.confirm || this.state.prompt ? (
<Button onClick={this.handleCancel}>{__(cancelText)}</Button>
) : null}
<Button
level={
this.state.confirm || this.state.prompt
? confirmBtnLevel
: alertBtnLevel
}
onClick={this.handleConfirm}
>
{finalConfirmText}
</Button>
</div>
) : null}
</Modal>
);
}
}
function renderForm(
controls: Array<any>,
value: PlainObject = {},
callback?: (values: PlainObject) => void,
scopeRef?: (value: any) => void
) {
return renderSchema(
{
name: 'form',
type: 'form',
wrapWithPanel: false,
mode: 'horizontal',
controls
},
{
data: value,
onFinished: callback,
scopeRef
},
{
session: 'prompt'
}
);
}
export const alert: (content: string, title?: string) => void = (
content,
title
@ -191,5 +289,12 @@ export const confirm: (
confirmText?: string
) => Promise<any> = (content, title, confirmText) =>
Alert.getInstance().confirm(content, title, confirmText);
export const prompt: (
controls: any,
defaultvalue?: any,
title?: string,
confirmText?: string
) => Promise<any> = (controls, defaultvalue, title, confirmText) =>
Alert.getInstance().prompt(controls, defaultvalue, title, confirmText);
export const FinnalAlert = themeable(localeable(Alert));
export default FinnalAlert;

View File

@ -5,7 +5,7 @@
*/
import NotFound from './404';
import {default as Alert, alert, confirm} from './Alert';
import {default as Alert, alert, confirm, prompt} from './Alert';
import {default as ContextMenu, openContextMenus} from './ContextMenu';
import AsideNav from './AsideNav';
import Button from './Button';
@ -57,10 +57,11 @@ export {
NotFound,
Alert as AlertComponent,
alert,
confirm,
prompt,
ContextMenu,
openContextMenus,
Alert2,
confirm,
AsideNav,
Button,
Checkbox,