mui-tiptap
Version:
A Material-UI (MUI) styled WYSIWYG rich text editor, using Tiptap
85 lines (84 loc) • 5.29 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const mui_1 = require("tss-react/mui");
const FieldContainer_1 = __importDefault(require("./FieldContainer"));
const MenuBar_1 = __importDefault(require("./MenuBar"));
const RichTextContent_1 = __importDefault(require("./RichTextContent"));
const context_1 = require("./context");
const useDebouncedFocus_1 = __importDefault(require("./hooks/useDebouncedFocus"));
const styles_1 = require("./styles");
const DebounceRender_1 = __importDefault(require("./utils/DebounceRender"));
const richTextFieldClasses = (0, styles_1.getUtilityClasses)("RichTextField", ["root", "standard", "outlined", "menuBar", "menuBarContent", "content"]);
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
const useStyles = (0, mui_1.makeStyles)({
name: { RichTextField },
uniqId: "E2Alw3", // https://docs.tss-react.dev/nested-selectors#ssr
})((theme, _params, classes) => {
return {
// This first class is added to allow convenient user overrides. Users can
// similarly override the other classes below.
root: {},
standard: {
// We don't need horizontal spacing when not using the outlined variant
[`& .${classes.content}`]: {
padding: theme.spacing(1.5, 0),
},
[`& .${classes.menuBarContent}`]: {
padding: theme.spacing(1, 0),
},
},
outlined: {
// Add padding around the input area and menu bar, since they're
// contained in the outline
[`& .${classes.content}`]: {
padding: theme.spacing(1.5),
},
[`& .${classes.menuBarContent}`]: {
padding: theme.spacing(1, 1.5),
},
},
menuBar: {},
menuBarContent: {},
content: {},
};
});
/**
* Renders the Tiptap rich text editor content and a controls menu bar.
*
* With the "outlined" variant, renders a bordered UI similar to the Material UI
* `TextField`. The "standard" variant does not have an outline/border.
*
* Must be a child of the RichTextEditorProvider so that the `editor` context is
* available.
*/
function RichTextField(_a) {
var _b, _c;
var { variant = "outlined", controls, disableDebounceRenderControls = false, disabled, className, classes: overrideClasses = {}, footer, MenuBarProps, RichTextContentProps } = _a, fieldContainerProps = __rest(_a, ["variant", "controls", "disableDebounceRenderControls", "disabled", "className", "classes", "footer", "MenuBarProps", "RichTextContentProps"]);
const { classes, cx } = useStyles(undefined, {
props: { classes: overrideClasses },
});
const editor = (0, context_1.useRichTextEditorContext)();
// Because the user interactions with the editor menu bar buttons unfocus the editor
// (since it's not part of the editor content), we'll debounce our visual focused
// state so that the (outlined) field focus styles don't "flash" whenever that happens
const isFieldFocused = (0, useDebouncedFocus_1.default)({ editor });
return ((0, jsx_runtime_1.jsxs)(FieldContainer_1.default, Object.assign({}, fieldContainerProps, { variant: variant, focused: !disabled && isFieldFocused, disabled: disabled, className: cx(richTextFieldClasses.root, classes.root, variant === "outlined"
? [richTextFieldClasses.outlined, classes.outlined]
: [richTextFieldClasses.standard, classes.standard], className), children: [controls && ((0, jsx_runtime_1.jsx)(MenuBar_1.default, Object.assign({}, MenuBarProps, { classes: Object.assign(Object.assign({}, MenuBarProps === null || MenuBarProps === void 0 ? void 0 : MenuBarProps.classes), { root: cx(richTextFieldClasses.menuBar, classes.menuBar, (_b = MenuBarProps === null || MenuBarProps === void 0 ? void 0 : MenuBarProps.classes) === null || _b === void 0 ? void 0 : _b.root), content: cx(richTextFieldClasses.content, classes.menuBarContent, (_c = MenuBarProps === null || MenuBarProps === void 0 ? void 0 : MenuBarProps.classes) === null || _c === void 0 ? void 0 : _c.content) }), children: disableDebounceRenderControls ? (controls) : ((0, jsx_runtime_1.jsx)(DebounceRender_1.default, { children: controls })) }))), (0, jsx_runtime_1.jsx)(RichTextContent_1.default, Object.assign({}, RichTextContentProps, { className: cx(richTextFieldClasses.content, classes.content, RichTextContentProps === null || RichTextContentProps === void 0 ? void 0 : RichTextContentProps.className) })), footer] })));
}
exports.default = RichTextField;
;