Introduce Spinner and Dialog.loading

Summary: Per title

Reviewed By: nikoant

Differential Revision: D29790505

fbshipit-source-id: 7c995be59418ffd4c337eb8d1905bd2f2466e5cd
This commit is contained in:
Michel Weststrate
2021-07-22 04:16:01 -07:00
committed by Facebook GitHub Bot
parent f74029699f
commit 62674da74e
5 changed files with 71 additions and 1 deletions

View File

@@ -43,6 +43,7 @@ test('Correct top level API exposed', () => {
"MasterDetail",
"NUX",
"Panel",
"Spinner",
"Tab",
"Tabs",
"TestUtils",

View File

@@ -92,6 +92,7 @@ export {createDataSource} from './state/createDataSource';
export {DataTable, DataTableColumn} from './ui/data-table/DataTable';
export {DataTableManager} from './ui/data-table/DataTableManager';
export {DataList} from './ui/DataList';
export {Spinner} from './ui/Spinner';
export {
Interactive as _Interactive,

View File

@@ -12,6 +12,7 @@ import {Atom, createState, useValue} from '../state/atom';
import React from 'react';
import {renderReactRoot} from '../utils/renderReactRoot';
import {Layout} from './Layout';
import {Spinner} from './Spinner';
type DialogResult<T> = Promise<false | T> & {close: () => void};
@@ -19,8 +20,11 @@ type BaseDialogOptions = {
title: string;
okText?: string;
cancelText?: string;
width?: number;
};
const defaultWidth = 400;
export const Dialog = {
show<T>(
opts: BaseDialogOptions & {
@@ -54,7 +58,7 @@ export const Dialog = {
}
}}
onCancel={cancel}
width={400}>
width={opts.width ?? defaultWidth}>
<Layout.Container gap>
{opts.children}
<SubmissionError submissionError={submissionError} />
@@ -112,6 +116,47 @@ export const Dialog = {
},
});
},
loading({
title,
message,
width,
}: {
title?: string;
message: string | React.ReactElement;
width?: number;
}) {
let cancel: () => void;
return Object.assign(
new Promise<void>((resolve) => {
renderReactRoot((hide) => {
cancel = () => {
hide();
resolve();
};
return (
<Modal
title={title ?? 'Loading...'}
visible
footer={null}
width={width ?? defaultWidth}
closable={false}>
<Layout.Container gap center>
<Spinner />
{message}
</Layout.Container>
</Modal>
);
});
}),
{
close() {
cancel();
},
},
);
},
};
function PromptInput({inputValue}: {inputValue: Atom<string>}) {

View File

@@ -0,0 +1,18 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {LoadingOutlined} from '@ant-design/icons';
import {Spin} from 'antd';
import React from 'react';
export function Spinner({size}: {size?: number}) {
return (
<Spin indicator={<LoadingOutlined style={{fontSize: size ?? 24}} spin />} />
);
}

View File

@@ -918,10 +918,15 @@ Available utilities
* `message`: Text accompanying the input
* `defaultValue`
* `onConfirm(value) => Promise<string>`. Can be used to transform the inputted value before resolving the prompt promise. If the handler throws, this will be shown as validation error in the dialog.
* `Dialog.loading(options): Promise<void>`. Shows a dialog with a loading spinner. This dialog cannot be closed by the user, so instead `.close()` should be called programmatically on the returned promise.
* `message`: Message to display with the loading spinner.
* `Dialog.show<T>(options): Promise<T | false`. Low level building block to build dialogs. Options:
* `children`: React Element to render as children of the dialog.
* `onConfirm: () => Promise<T>`. Handler to handle the OK button, which should produce the value the `Dialog.show` call will resolve to.
### Spinner
Shows a loading spinner. Accept an optional `size` to make the spinner larger / smaller.
### NUX