mui-tiptap
Version:
A Material-UI (MUI) styled WYSIWYG rich text editor, using Tiptap
100 lines (99 loc) • 5.95 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 });
exports.default = RichTextField;
const jsx_runtime_1 = require("react/jsx-runtime");
const styles_1 = require("@mui/material/styles");
const clsx_1 = require("clsx");
const FieldContainer_1 = __importDefault(require("./FieldContainer"));
const MenuBar_1 = __importDefault(require("./MenuBar"));
const RichTextContent_1 = __importDefault(require("./RichTextContent"));
const RichTextField_classes_1 = require("./RichTextField.classes");
const context_1 = require("./context");
const useDebouncedFocus_1 = __importDefault(require("./hooks/useDebouncedFocus"));
const styles_2 = require("./styles");
const DebounceRender_1 = __importDefault(require("./utils/DebounceRender"));
const componentName = (0, styles_2.getUtilityComponentName)("RichTextField");
const RichTextFieldRoot = (0, styles_1.styled)(FieldContainer_1.default, {
name: componentName,
slot: "root",
overridesResolver: (props, styles) => [
styles.root,
props.ownerState.variant === "outlined" && styles.outlined,
props.ownerState.variant === "standard" && styles.standard,
],
})(({ theme, ownerState }) => (Object.assign(Object.assign({}, (ownerState.variant === "standard" && {
// We don't need horizontal spacing when not using the outlined variant
[`& .${RichTextField_classes_1.richTextFieldClasses.content}`]: {
padding: theme.spacing(1.5, 0),
},
[`& .${RichTextField_classes_1.richTextFieldClasses.menuBarContent}`]: {
padding: theme.spacing(1, 0),
},
})), (ownerState.variant === "outlined" && {
// Add padding around the input area and menu bar, since they're
// contained in the outline
[`& .${RichTextField_classes_1.richTextFieldClasses.content}`]: {
padding: theme.spacing(1.5),
},
[`& .${RichTextField_classes_1.richTextFieldClasses.menuBarContent}`]: {
padding: theme.spacing(1, 1.5),
},
}))));
/**
* 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(inProps) {
var _a, _b;
const props = (0, styles_1.useThemeProps)({ props: inProps, name: componentName });
const { variant = "outlined", controls, disableDebounceRenderControls = false, disabled, className, classes = {}, footer, MenuBarProps, RichTextContentProps, sx } = props, fieldContainerProps = __rest(props, ["variant", "controls", "disableDebounceRenderControls", "disabled", "className", "classes", "footer", "MenuBarProps", "RichTextContentProps", "sx"]);
const editor = (0, context_1.useRichTextEditorContext)();
const ownerState = {
variant,
disabled,
disableDebounceRenderControls,
};
// 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)(RichTextFieldRoot, Object.assign({}, fieldContainerProps, { variant: variant, focused: !disabled && isFieldFocused, disabled: disabled, className: (0, clsx_1.clsx)([
RichTextField_classes_1.richTextFieldClasses.root,
classes.root,
variant === "outlined"
? [RichTextField_classes_1.richTextFieldClasses.outlined, classes.outlined]
: [RichTextField_classes_1.richTextFieldClasses.standard, classes.standard],
className,
]), ownerState: ownerState, sx: sx, 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: (0, clsx_1.clsx)([
RichTextField_classes_1.richTextFieldClasses.menuBar,
classes.menuBar,
(_a = MenuBarProps === null || MenuBarProps === void 0 ? void 0 : MenuBarProps.classes) === null || _a === void 0 ? void 0 : _a.root,
]), content: (0, clsx_1.clsx)([
RichTextField_classes_1.richTextFieldClasses.menuBarContent,
classes.menuBarContent,
(_b = MenuBarProps === null || MenuBarProps === void 0 ? void 0 : MenuBarProps.classes) === null || _b === void 0 ? void 0 : _b.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: (0, clsx_1.clsx)([
RichTextField_classes_1.richTextFieldClasses.content,
classes.content,
RichTextContentProps === null || RichTextContentProps === void 0 ? void 0 : RichTextContentProps.className,
]) })), footer] })));
}