UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

392 lines (391 loc) 22 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.NotifierMU = exports.NotificationMU = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const notificationbase_1 = require("@etsoo/notificationbase"); const shared_1 = require("@etsoo/shared"); const react_1 = __importDefault(require("react")); const react_2 = require("@etsoo/react"); const DraggablePaperComponent_1 = require("./DraggablePaperComponent"); const LoadingButton_1 = require("./LoadingButton"); const Labels_1 = require("./app/Labels"); const DialogTitle_1 = __importDefault(require("@mui/material/DialogTitle")); const styles_1 = require("@mui/material/styles"); const Dialog_1 = __importDefault(require("@mui/material/Dialog")); const IconButton_1 = __importDefault(require("@mui/material/IconButton")); const DialogContent_1 = __importDefault(require("@mui/material/DialogContent")); const DialogActions_1 = __importDefault(require("@mui/material/DialogActions")); const DialogContentText_1 = __importDefault(require("@mui/material/DialogContentText")); const Fade_1 = __importDefault(require("@mui/material/Fade")); const Alert_1 = __importDefault(require("@mui/material/Alert")); const AlertTitle_1 = __importDefault(require("@mui/material/AlertTitle")); const Switch_1 = __importDefault(require("@mui/material/Switch")); const Slider_1 = __importDefault(require("@mui/material/Slider")); const TextField_1 = __importDefault(require("@mui/material/TextField")); const Typography_1 = __importDefault(require("@mui/material/Typography")); const Button_1 = __importDefault(require("@mui/material/Button")); const Popover_1 = __importDefault(require("@mui/material/Popover")); const CircularProgress_1 = __importDefault(require("@mui/material/CircularProgress")); const Backdrop_1 = __importDefault(require("@mui/material/Backdrop")); const Box_1 = __importDefault(require("@mui/material/Box")); const Snackbar_1 = __importDefault(require("@mui/material/Snackbar")); const Close_1 = __importDefault(require("@mui/icons-material/Close")); const Done_1 = __importDefault(require("@mui/icons-material/Done")); const Info_1 = __importDefault(require("@mui/icons-material/Info")); const Warning_1 = __importDefault(require("@mui/icons-material/Warning")); const Error_1 = __importDefault(require("@mui/icons-material/Error")); const Help_1 = __importDefault(require("@mui/icons-material/Help")); // Custom icon dialog title bar const IconDialogTitle = (0, styles_1.styled)(DialogTitle_1.default, { // Prevent the passing of the draggable prop to the underlying DOM element shouldForwardProp: (prop) => prop !== "draggable" }) ` ${({ theme, draggable }) => ` cursor: ${draggable ? "move" : "default"}; display: flex; align-items: center; & .dialogTitle { font-weight: bold; font-size: 1.17em; flex-grow: 3; text-overflow: ellipsis; padding-left: ${theme.spacing(1)}; } & .MuiDialogContent-root-close-button { padding-left: ${theme.spacing(1)}; } `} `; /** * MU notification */ class NotificationMU extends react_2.NotificationReact { // Create alert createAlert(_props, className) { const labels = Labels_1.Labels.NotificationMU; const { buttons, inputs, fullScreen, fullWidth = true, maxWidth, okLabel = labels.alertOK, primaryButton = true, primaryButtonProps, closable = false, draggable = fullScreen === true ? false : true } = this.inputProps ?? {}; let title = this.title; let icon; if (this.type === notificationbase_1.NotificationMessageType.Success) { icon = (0, jsx_runtime_1.jsx)(Done_1.default, { color: "primary" }); title ??= labels.success; } else if (this.type === notificationbase_1.NotificationMessageType.Info) { icon = (0, jsx_runtime_1.jsx)(Info_1.default, {}); title ??= labels.info; } else if (this.type === notificationbase_1.NotificationMessageType.Warning) { icon = (0, jsx_runtime_1.jsx)(Warning_1.default, { color: "secondary" }); title ??= labels.warning; } else { icon = (0, jsx_runtime_1.jsx)(Error_1.default, { color: "error" }); title ??= labels.alertTitle; } const setupProps = { color: "primary" }; // Setup callback const options = this.renderSetup ? this.renderSetup(setupProps) : undefined; // Callback const callback = async (_event) => { await this.returnValue(undefined); return true; }; return ((0, jsx_runtime_1.jsxs)(Dialog_1.default, { open: this.open, PaperComponent: draggable ? DraggablePaperComponent_1.DraggablePaperComponent : undefined, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen, ...options, children: [(0, jsx_runtime_1.jsxs)(IconDialogTitle, { draggable: draggable, className: draggable ? "dialog-title draggable-dialog-title" : "dialog-title", children: [icon, (0, jsx_runtime_1.jsx)("span", { className: "dialogTitle", children: title }), closable && ((0, jsx_runtime_1.jsx)(IconButton_1.default, { className: "MuiDialogContent-root-close-button", size: "small", onClick: () => this.returnValue("CLOSE"), children: (0, jsx_runtime_1.jsx)(Close_1.default, {}) }))] }), (0, jsx_runtime_1.jsxs)(DialogContent_1.default, { children: [typeof this.content === "string" ? ((0, jsx_runtime_1.jsx)(DialogContentText_1.default, { children: this.content })) : (this.content), inputs] }), (0, jsx_runtime_1.jsx)(DialogActions_1.default, { children: buttons ? buttons(this, callback) : primaryButton && ((0, jsx_runtime_1.jsx)(LoadingButton_1.LoadingButton, { ...setupProps, onClick: callback, autoFocus: true, ...primaryButtonProps, children: okLabel })) })] }, this.id)); } // Create confirm createConfirm(_props, className) { const labels = Labels_1.Labels.NotificationMU; const title = this.title ?? labels.confirmTitle; const { buttons, okLabel = labels.confirmYes, cancelLabel = labels.confirmNo, cancelButton = true, inputs, fullScreen, fullWidth = true, maxWidth, primaryButton = true, primaryButtonProps, closable = false, draggable = fullScreen === true ? false : true } = this.inputProps ?? {}; // Setup callback const options = this.renderSetup ? this.renderSetup({}) : undefined; const callback = async (_event, value) => { await this.returnValue(value); return true; }; return ((0, jsx_runtime_1.jsxs)(Dialog_1.default, { open: this.open, PaperComponent: draggable ? DraggablePaperComponent_1.DraggablePaperComponent : undefined, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen, ...options, children: [(0, jsx_runtime_1.jsxs)(IconDialogTitle, { draggable: draggable, className: draggable ? "dialog-title draggable-dialog-title" : "dialog-title", children: [(0, jsx_runtime_1.jsx)(Help_1.default, { color: "action" }), (0, jsx_runtime_1.jsx)("span", { className: "dialogTitle", children: title }), closable && ((0, jsx_runtime_1.jsx)(IconButton_1.default, { className: "MuiDialogContent-root-close-button", size: "small", onClick: () => this.returnValue("CLOSE"), children: (0, jsx_runtime_1.jsx)(Close_1.default, {}) }))] }), (0, jsx_runtime_1.jsxs)(DialogContent_1.default, { children: [typeof this.content === "string" ? ((0, jsx_runtime_1.jsx)(DialogContentText_1.default, { children: this.content })) : (this.content), inputs] }), (0, jsx_runtime_1.jsx)(DialogActions_1.default, { children: buttons ? (buttons(this, callback)) : ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [cancelButton && ((0, jsx_runtime_1.jsx)(LoadingButton_1.LoadingButton, { color: "secondary", onClick: async (event) => await callback(event, false), children: cancelLabel })), primaryButton && ((0, jsx_runtime_1.jsx)(LoadingButton_1.LoadingButton, { color: "primary", onClick: async (event) => await callback(event, true), autoFocus: true, ...primaryButtonProps, children: okLabel }))] })) })] }, this.id)); } createMessageColor() { if (this.type === notificationbase_1.NotificationMessageType.Danger) return "error"; if (this.type === notificationbase_1.NotificationMessageType.Success) return "success"; if (this.type === notificationbase_1.NotificationMessageType.Warning) return "warning"; return "info"; } // Create message createMessage(props, className) { if (!this.open) return (0, jsx_runtime_1.jsx)(react_1.default.Fragment, {}, this.id); const { closable = false } = props; const setupProps = { severity: this.createMessageColor(), variant: "filled" }; // Setup callback const options = this.renderSetup ? this.renderSetup(setupProps) : undefined; return ((0, jsx_runtime_1.jsx)(Fade_1.default, { in: true, children: (0, jsx_runtime_1.jsxs)(Alert_1.default, { ...setupProps, ...options, action: closable ? ((0, jsx_runtime_1.jsx)(IconButton_1.default, { size: "small", onClick: () => this.returnValue("CLOSE"), children: (0, jsx_runtime_1.jsx)(Close_1.default, {}) })) : undefined, onClose: () => this.dismiss(), className: className, children: [this.title && (0, jsx_runtime_1.jsx)(AlertTitle_1.default, { children: this.title }), this.content] }) }, this.id)); } // Create prompt createPrompt(_props, className) { const labels = Labels_1.Labels.NotificationMU; const title = this.title ?? labels.promptTitle; const { buttons, cancelLabel = labels.promptCancel, okLabel = labels.promptOK, cancelButton = true, inputs, type, fullScreen, fullWidth = true, maxWidth, primaryButton = true, primaryButtonProps, inputProps, closable = false, draggable = fullScreen === true ? false : true } = this.inputProps ?? {}; const inputRef = react_1.default.createRef(); const errorRef = react_1.default.createRef(); const setError = (error) => { if (errorRef.current == null) return; errorRef.current.innerText = error ?? ""; }; const handleSubmit = async (event) => { // Result let result = undefined; const input = inputRef.current; if (this.onReturn) { // Inputs case, no HTMLForm set to value, set the current form if (inputs && value == null) value = event.currentTarget.form; if (input) { if (type === "switch") { const boolValue = input.value === "true"; result = this.onReturn(boolValue); } else { const inputValue = shared_1.DomUtils.getInputValue(input); if ((inputValue == null || inputValue === "") && input.required) { input.focus(); return false; } result = this.onReturn(inputValue); } } else if (value != null) { result = this.onReturn(value); } } // Get the value // returns false to prevent default dismiss const v = await result; if (v === false) { input?.focus(); return false; } if (typeof v === "string") { setError(v); input?.focus(); return false; } this.dismiss(); return true; }; let localInputs; let value = undefined; if (inputs == null) { if (type === "switch") { localInputs = ((0, jsx_runtime_1.jsx)(Switch_1.default, { inputRef: inputRef, ...inputProps, value: "true", autoFocus: true, required: true })); } else if (type === "slider") { localInputs = (0, jsx_runtime_1.jsx)(Slider_1.default, { onChange: (_e, v) => (value = v) }); } else { localInputs = ((0, jsx_runtime_1.jsx)(TextField_1.default, { inputRef: inputRef, onChange: () => setError(undefined), autoFocus: true, margin: "dense", fullWidth: true, type: type, required: true, ...inputProps })); } } else { localInputs = inputs; } // Setup callback const options = this.renderSetup ? this.renderSetup({}) : undefined; return ((0, jsx_runtime_1.jsx)(Dialog_1.default, { open: this.open, PaperComponent: draggable ? DraggablePaperComponent_1.DraggablePaperComponent : undefined, className: className, fullWidth: fullWidth, maxWidth: maxWidth, fullScreen: fullScreen, ...options, children: (0, jsx_runtime_1.jsxs)("form", { onSubmit: (event) => { event.preventDefault(); event.currentTarget.elements.namedItem("okButton")?.click(); return false; }, children: [(0, jsx_runtime_1.jsxs)(IconDialogTitle, { draggable: draggable, className: draggable ? "dialog-title draggable-dialog-title" : "dialog-title", children: [(0, jsx_runtime_1.jsx)(Info_1.default, { color: "primary" }), (0, jsx_runtime_1.jsx)("span", { className: "dialogTitle", children: title }), closable && ((0, jsx_runtime_1.jsx)(IconButton_1.default, { className: "MuiDialogContent-root-close-button", size: "small", onClick: () => this.returnValue("CLOSE"), children: (0, jsx_runtime_1.jsx)(Close_1.default, {}) }))] }), (0, jsx_runtime_1.jsxs)(DialogContent_1.default, { children: [typeof this.content === "string" ? ((0, jsx_runtime_1.jsx)(DialogContentText_1.default, { children: this.content })) : (this.content), localInputs, (0, jsx_runtime_1.jsx)(Typography_1.default, { variant: "caption", display: "block", ref: errorRef, color: "error" })] }), (0, jsx_runtime_1.jsx)(DialogActions_1.default, { children: buttons ? (buttons(this, handleSubmit)) : ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [cancelButton && ((0, jsx_runtime_1.jsx)(Button_1.default, { color: "secondary", onClick: () => { if (this.onReturn) this.onReturn(undefined); this.dismiss(); }, children: cancelLabel })), primaryButton && ((0, jsx_runtime_1.jsx)(LoadingButton_1.LoadingButton, { color: "primary", autoFocus: true, onClick: handleSubmit, name: "okButton", ...primaryButtonProps, children: okLabel }))] })) })] }) }, this.id)); } createPopup(_props, className) { // Destruct // dismiss will trigger onReturn callback const { content, id, open } = this; // Setup callback const options = this.renderSetup ? this.renderSetup({}) : undefined; return ((0, jsx_runtime_1.jsx)(Popover_1.default, { open: open, className: className, onClose: () => this.dismiss(), ...options, children: content }, id)); } // Create loading createLoading(_props, className) { // Properties const setupProps = { color: "primary" }; const labels = Labels_1.Labels.NotificationMU; // Input props const { maxWidth = "xs" } = this.inputProps ?? {}; // Content let content = this.content; if (content === "@") content = labels.loading.toString(); // Setup callback const options = this.renderSetup ? this.renderSetup(setupProps) : undefined; return ((0, jsx_runtime_1.jsx)(Backdrop_1.default, { className: className, sx: { color: "#fff", zIndex: (theme) => theme.zIndex.modal + 1 }, open: this.open, ...options, children: (0, jsx_runtime_1.jsxs)(Box_1.default, { display: "flex", flexDirection: "column", flexWrap: "nowrap", alignItems: "center", sx: { "& > :not(style) + :not(style)": { marginTop: (theme) => theme.spacing(1) } }, children: [(0, jsx_runtime_1.jsx)(CircularProgress_1.default, { ...setupProps }), content && ((0, jsx_runtime_1.jsx)(Box_1.default, { maxWidth: maxWidth === false ? undefined : maxWidth, children: content }))] }) }, this.id)); } /** * Render method * @param props Props * @param className Style class name * @param classes Style classes */ render(props, className) { // Loading bar if (this.type === notificationbase_1.NotificationType.Loading) { return this.createLoading(props, className); } else if (this.type === notificationbase_1.NotificationType.Confirm) { return this.createConfirm(props, className); } else if (this.type === notificationbase_1.NotificationType.Prompt) { return this.createPrompt(props, className); } else if (this.type === notificationbase_1.NotificationType.Popup) { return this.createPopup(props, className); } else if (this.type === notificationbase_1.NotificationType.Error || (this.modal && this.type in notificationbase_1.NotificationMessageType)) { // Alert or modal message return this.createAlert(props, className); } else { return this.createMessage(props, className); } } } exports.NotificationMU = NotificationMU; /** * Antd notifier */ class NotifierMU extends react_2.NotifierReact { /** * Create state and return provider * @param className Style class name * @param debug Debug mode * @returns Provider */ static setup(className, debug = false) { className ??= "notifier-mu"; // Create an instance const instance = new NotifierMU(); instance.debug = debug; const provider = instance.createProvider(className, debug); react_2.NotifierReact.updateInstance(instance); return provider; } // Calculate origin from align property static getOrigin(align) { if (align === notificationbase_1.NotificationAlign.TopLeft) { return { horizontal: "left", vertical: "top" }; } if (align === notificationbase_1.NotificationAlign.TopCenter) { return { horizontal: "center", vertical: "top" }; } if (align === notificationbase_1.NotificationAlign.TopRight) { return { horizontal: "right", vertical: "top" }; } if (align === notificationbase_1.NotificationAlign.BottomLeft) { return { horizontal: "left", vertical: "bottom" }; } if (align === notificationbase_1.NotificationAlign.BottomCenter) { return { horizontal: "center", vertical: "bottom" }; } if (align === notificationbase_1.NotificationAlign.BottomRight) { return { horizontal: "right", vertical: "bottom" }; } return { horizontal: "center", vertical: "top" }; } /** * Create align container * @param align Align * @param children Children * @param options Other options */ createContainer = (align, children) => { // Each align group, class equal to something similar to 'align-topleft' const alignText = notificationbase_1.NotificationAlign[align].toLowerCase(); let className = `align-${alignText}`; if (children.length === 0) { return (0, jsx_runtime_1.jsx)("div", { className: className }, `empty-${alignText}`); } if (align === notificationbase_1.NotificationAlign.Unknown) { // div container for style control return ((0, jsx_runtime_1.jsx)("div", { className: className, children: children }, `div-${alignText}`)); } // Use SnackBar for layout return ((0, jsx_runtime_1.jsx)(Snackbar_1.default, { anchorOrigin: NotifierMU.getOrigin(align), className: className, sx: align === notificationbase_1.NotificationAlign.Center ? { position: "fixed", top: "50%!important" } : undefined, open: true, children: (0, jsx_runtime_1.jsx)(Box_1.default, { display: "flex", flexDirection: "column", flexWrap: "nowrap", sx: { "& > :not(style) + :not(style)": { marginTop: (theme) => theme.spacing(1) } }, children: children }, `box-${alignText}`) }, `layout-${alignText}`)); }; /** * Add raw definition * @param data Notification data definition * @param modal Show as modal */ addRaw(data, modal) { // Destruct const { type, content, title, align, timespan = modal ? 0 : undefined, ...rest } = data; if (this.debug) { console.debug("NotificationMU.addRaw", data); } // Setup const n = new NotificationMU(type, content, title, align, timespan); // Assign other properties Object.assign(n, rest); // Is modal if (modal != null) n.modal = modal; // Add to the collection this.add(n); // Return return n; } } exports.NotifierMU = NotifierMU;