mui-tiptap
Version:
A Material-UI (MUI) styled WYSIWYG rich text editor, using Tiptap
161 lines (160 loc) • 8.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
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 = MenuSelect;
const jsx_runtime_1 = require("react/jsx-runtime");
const OutlinedInput_1 = require("@mui/material/OutlinedInput");
const Select_1 = __importStar(require("@mui/material/Select"));
const styles_1 = require("@mui/material/styles");
const SvgIcon_1 = require("@mui/material/SvgIcon");
const clsx_1 = require("clsx");
const react_1 = require("react");
const styles_2 = require("../styles");
const MenuButtonTooltip_1 = __importDefault(require("./MenuButtonTooltip"));
const MenuSelect_classes_1 = require("./MenuSelect.classes");
const componentName = (0, styles_2.getUtilityComponentName)("MenuSelect");
const MenuSelectRoot = (0, styles_1.styled)(Select_1.default, {
name: componentName,
slot: "root",
overridesResolver: (props, styles) => styles.root,
})(({ theme }) => ({
// Don't show the default outline when not hovering or focused, for better
// style consistency with the MenuButtons
[`&:not(:hover):not(.${OutlinedInput_1.outlinedInputClasses.focused}) .${OutlinedInput_1.outlinedInputClasses.notchedOutline}`]: {
borderWidth: 0,
},
[`& .${SvgIcon_1.svgIconClasses.root}`]: {
// Ensure that if an icon is used as the `renderValue` result, it uses
// the same color as the default ToggleButton icon and the Select
// dropdown arrow icon
// https://github.com/mui/material-ui/blob/2cb9664b16d5a862a3796add7c8e3b088b47acb5/packages/mui-material/src/ToggleButton/ToggleButton.js#L60,
// https://github.com/mui/material-ui/blob/0b7beb93c9015da6e35c2a31510f679126cf0de1/packages/mui-material/src/NativeSelect/NativeSelectInput.js#L96
color: theme.palette.action.active,
},
[`&.${Select_1.selectClasses.disabled} .${SvgIcon_1.svgIconClasses.root}`]: {
// Matching
// https://github.com/mui/material-ui/blob/2cb9664b16d5a862a3796add7c8e3b088b47acb5/packages/mui-material/src/ToggleButton/ToggleButton.js#L65
color: theme.palette.action.disabled,
},
[`& .${Select_1.selectClasses.select}`]: {
paddingTop: "3px",
paddingBottom: "3px",
fontSize: "0.9em",
},
// Increase specificity to override MUI's styles
[`&&& .${Select_1.selectClasses.select}`]: {
paddingLeft: theme.spacing(1),
paddingRight: theme.spacing(3),
},
[`& .${Select_1.selectClasses.icon}`]: {
// Move the caret icon closer to the right than default so the button is
// more compact
right: 1,
},
// The type casting below is a hacky workaround to support generics with the
// `styled` wrapper, per https://stackoverflow.com/a/72163115,
// https://github.com/mui/material-ui/blob/7e90b18d0e21ece648e5074970900b05fea03989/docs/data/material/guides/typescript/typescript.md#complications-with-the-component-prop
}));
const MenuSelectTooltip = (0, styles_1.styled)(MenuButtonTooltip_1.default, {
name: componentName,
slot: "tooltip",
overridesResolver: (props, styles) => styles.tooltip,
})({
display: "inline-flex",
});
/** A Select that is styled to work well with other menu bar controls. */
function MenuSelect(inProps) {
const props = (0, styles_1.useThemeProps)({ props: inProps, name: componentName });
const { tooltipTitle, classes = {}, sx } = props, selectProps = __rest(props, ["tooltipTitle", "classes", "sx"]);
// We use a controlled tooltip here because otherwise it seems the tooltip can
// get stuck open after selecting something (as it can re-trigger the
// Tooltip's onOpen upon clicking a MenuItem). We instead trigger it to
// open/close based on interaction specifically with the Select (not the usual
// Tooltip onOpen/onClose)
const [tooltipOpen, setTooltipOpen] = (0, react_1.useState)(false);
const select = ((0, jsx_runtime_1.jsx)(MenuSelectRoot, Object.assign({ margin: "none", variant: "outlined", size: "small" }, selectProps, { inputProps: Object.assign({
// Fall back to tooltipTitle as an accessible name for the combobox
// element if no aria-label is provided via `inputProps` or
// `slotProps.input`. Note that neither the Tooltip itself nor a
// top-level aria-label on Select would reach the combobox.
"aria-label": tooltipTitle }, selectProps.inputProps), onMouseEnter: (...args) => {
var _a;
setTooltipOpen(true);
(_a = selectProps.onMouseEnter) === null || _a === void 0 ? void 0 : _a.call(selectProps, ...args);
}, onMouseLeave: (...args) => {
var _a;
setTooltipOpen(false);
(_a = selectProps.onMouseLeave) === null || _a === void 0 ? void 0 : _a.call(selectProps, ...args);
}, onClick: (...args) => {
var _a;
setTooltipOpen(false);
(_a = selectProps.onClick) === null || _a === void 0 ? void 0 : _a.call(selectProps, ...args);
}, onOpen: (...args) => {
var _a;
// Close the tooltip when the dropdown is opened. This can ensure the
// tooltip doesn't block menu items, etc. (see
// https://github.com/sjdemartini/mui-tiptap/issues/308).
setTooltipOpen(false);
(_a = selectProps.onOpen) === null || _a === void 0 ? void 0 : _a.call(selectProps, ...args);
},
// Always show the dropdown options directly below the select input,
// aligned to left-most edge
MenuProps: Object.assign({ anchorOrigin: {
vertical: "bottom",
horizontal: "left",
}, transformOrigin: {
vertical: "top",
horizontal: "left",
} }, selectProps.MenuProps), className: (0, clsx_1.clsx)([
MenuSelect_classes_1.menuSelectClasses.root,
classes.root,
selectProps.className,
]), sx: sx })));
return tooltipTitle ? ((0, jsx_runtime_1.jsx)(MenuSelectTooltip, { label: tooltipTitle, open: tooltipOpen, className: (0, clsx_1.clsx)([MenuSelect_classes_1.menuSelectClasses.tooltip, classes.tooltip]), children: select })) : (select);
}