flipper-plugin
Version:
Flipper Desktop plugin SDK and components
172 lines • 7.28 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Dialog = void 0;
const antd_1 = require("antd");
const atom_1 = require("../state/atom");
const react_1 = __importDefault(require("react"));
const renderReactRoot_1 = require("../utils/renderReactRoot");
const Layout_1 = require("./Layout");
const Spinner_1 = require("./Spinner");
const defaultWidth = 400;
exports.Dialog = {
show(opts) {
let cancel;
return Object.assign(new Promise((resolve) => {
const state = (0, atom_1.createState)(opts.defaultValue);
const submissionError = (0, atom_1.createState)('');
// create inline component to subscribe to dialog state
const DialogComponent = ({ onHide }) => {
const currentValue = (0, atom_1.useValue)(state);
const currentError = (0, atom_1.useValue)(submissionError);
const setCurrentValue = (v) => {
state.set(v);
if (opts.onValidate) {
submissionError.set(opts.onValidate(v));
}
};
return (react_1.default.createElement(antd_1.Modal, { title: opts.title, open: true, okText: opts.okText, cancelText: opts.cancelText, onOk: async () => {
try {
const value = opts.onConfirm
? await opts.onConfirm(currentValue)
: // TODO: Fix this the next time the file is edited.
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
currentValue;
onHide();
resolve(value);
}
catch (e) {
submissionError.set(e.toString());
}
}, okButtonProps: {
disabled: opts.onValidate
? !!opts.onValidate(currentValue) // non-falsy value means validation error
: false,
...opts.okButtonProps,
}, cancelButtonProps: opts.cancelButtonProps, onCancel: cancel, width: opts.width ?? defaultWidth },
react_1.default.createElement(Layout_1.Layout.Container, { gap: true },
opts.children(currentValue, setCurrentValue),
currentError && react_1.default.createElement(antd_1.Alert, { type: "error", message: currentError }))));
};
(0, renderReactRoot_1.renderReactRoot)((hide) => {
cancel = () => {
hide();
resolve(false);
};
return react_1.default.createElement(DialogComponent, { onHide: hide });
});
}), {
close() {
cancel();
},
});
},
/**
* Shows an item in the modal stack, but without providing any further UI, like .show does.
*/
showModal(fn) {
let cancel;
return Object.assign(new Promise((resolve) => {
(0, renderReactRoot_1.renderReactRoot)((hide) => {
cancel = () => {
hide();
resolve(false);
};
return fn((result) => {
hide();
resolve(result ?? false);
});
});
}), {
close() {
cancel();
},
});
},
confirm({ message, onConfirm, ...rest }) {
return exports.Dialog.show({
...rest,
defaultValue: true,
children: () => message,
onConfirm,
});
},
alert({ message, type, ...rest }) {
let modalRef;
return Object.assign(new Promise((resolve) => {
modalRef = antd_1.Modal[type]({
afterClose: resolve,
content: message,
...rest,
});
}), {
close() {
modalRef.destroy();
},
});
},
prompt({ message, defaultValue, onConfirm, ...rest }) {
return exports.Dialog.show({
...rest,
defaultValue: defaultValue ?? '',
children: (value, onChange) => (react_1.default.createElement(Layout_1.Layout.Container, { gap: true },
react_1.default.createElement(antd_1.Typography.Text, null, message),
react_1.default.createElement(antd_1.Input, { value: value, onChange: (e) => onChange(e.target.value) }))),
onValidate: (value) => (value ? '' : 'No input provided'),
onConfirm,
});
},
options({ message, onConfirm, options, ...rest }) {
return exports.Dialog.show({
...rest,
defaultValue: undefined,
onValidate: (value) => value === undefined ? 'Please select an option' : '',
children: (value, onChange) => (react_1.default.createElement(Layout_1.Layout.Container, { gap: true, style: { maxHeight: '50vh', overflow: 'auto' } },
react_1.default.createElement(antd_1.Typography.Text, null, message),
react_1.default.createElement(antd_1.Radio.Group, { value: value, onChange: (e) => {
onChange(e.target.value);
} },
react_1.default.createElement(antd_1.Space, { direction: "vertical" }, options.map((o) => (react_1.default.createElement(antd_1.Radio, { value: o.value, key: o.value }, o.label))))))),
onConfirm,
});
},
select({ defaultValue, renderer, onValidate, ...rest }) {
const handle = exports.Dialog.show({
...rest,
defaultValue,
onValidate,
children: (currentValue, setValue) => renderer(currentValue, setValue, () => handle.close()),
});
return handle;
},
loading({ title, message, width, }) {
let cancel;
return Object.assign(new Promise((resolve) => {
(0, renderReactRoot_1.renderReactRoot)((hide) => {
cancel = () => {
hide();
resolve();
};
return (react_1.default.createElement(antd_1.Modal, { title: title ?? 'Loading...', open: true, footer: null, width: width ?? defaultWidth, closable: false },
react_1.default.createElement(Layout_1.Layout.Container, { gap: true, center: true },
react_1.default.createElement(Spinner_1.Spinner, null),
message)));
});
}), {
close() {
cancel();
},
});
},
};
//# sourceMappingURL=Dialog.js.map
;