UNPKG

flipper-plugin

Version:

Flipper Desktop plugin SDK and components

172 lines 7.28 kB
"use strict"; /** * 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