@prisma-cms/front-editor
Version:
163 lines • 6.97 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
// import Context from './Context';
// import { HtmlTagProps } from '../../Tag/HtmlTag';
const useMutationObserver_1 = __importDefault(require("./hooks/useMutationObserver"));
const interfaces_1 = require("./interfaces");
// import TagEditor from '../TagEditor'
const styles_1 = require("./styles");
const contentEditable_1 = require("./styles/contentEditable");
const Toolbar_1 = __importDefault(require("./Toolbar"));
/**
* Компонент-обертка для contenteditable элемента.
* Предназначение: дать возможность редактировать содержимое в браузере.
* Особенности:
* - внутренние теги, формируемые реакт-компонентами не редактировать.
* - Selection есть всегда. Просто не всегда есть фокус-теги. Меняется при клике в любую часть документа.
* Сценарий:
* - По клику делать компонент редактируемый
* - По выходу из области делать его опять не редактируемым
*/
const ContentProxy = (props) => {
const {
// components,
// editable,
// initialContent,
// mode = 'main',
// TagEditor,
// updateObject: updateObjectProps,
updateObject, className,
// ...other
children, experimental, } = props;
// const updateObject = useCallback((data) => {
// console.log('ContentProxy updateObject data', data);
// updateObjectProps(data);
// }, [
// updateObjectProps
// ]);
const [editMode, setEditMode] = react_1.useState(null);
// const ref = useRef<HTMLDivElement>(null);
// const [wrapper, setWrapper] = useState<HTMLDivElement | null>(null);
const [contentEditableContainer, setContentEditableContainer] = react_1.useState(null);
const [newContent, setNewContent] = react_1.useState(null);
/**
* Сохраняем временный контент в JSON компонента
*/
const saveChanges = react_1.useCallback(() => {
if (!newContent) {
return false;
}
/**
* Выключаем режим редактирования
*/
setEditMode(null);
/**
* Обновляем компонент
*/
updateObject({
components: newContent || [],
});
/**
* Сбрасываем временный контент
*/
setNewContent(null);
return true;
}, [newContent, updateObject]);
const [focused, setFocused] = react_1.useState(false);
const onFocus = react_1.useCallback(() => {
return setFocused(true);
}, []);
const onBlur = react_1.useCallback(() => {
// Сохраняем изменения, если есть
saveChanges();
return setFocused(false);
}, [saveChanges]);
/**
* Find closest node
*/
// useMutationObserver(ref.current, setNewContent);
useMutationObserver_1.default(contentEditableContainer, setNewContent, editMode);
const selection = react_1.useMemo(() => { var _a, _b; return (_b = (_a = global.document) === null || _a === void 0 ? void 0 : _a.getSelection()) !== null && _b !== void 0 ? _b : null; }, []);
const closestInSelection = react_1.useCallback((selector) => {
var _a;
if (!(selection === null || selection === void 0 ? void 0 : selection.focusNode)) {
return null;
}
let node = selection.focusNode;
if (node.nodeType === Node.TEXT_NODE) {
node = (_a = selection.focusNode) === null || _a === void 0 ? void 0 : _a.parentNode;
}
if (node && node instanceof Element) {
return node.closest(selector);
}
return null;
}, [selection]);
const contentProxy = react_1.useMemo(() => {
return (react_1.default.createElement(styles_1.ContentProxyStyled
// ref={setWrapper}
// suppressContentEditableWarning
// contentEditable={true}
// onFocus={onFocus}
// onBlur={onBlur}
, {
// ref={setWrapper}
// suppressContentEditableWarning
// contentEditable={true}
// onFocus={onFocus}
// onBlur={onBlur}
className: [
className,
'ContentProxyStyled',
focused ? 'focused' : '',
].join(' ') },
react_1.default.createElement(Toolbar_1.default
// selection={selection}
, {
// selection={selection}
closestInSelection: closestInSelection, newContent: newContent, saveChanges: saveChanges, editMode: editMode, setEditMode: setEditMode, contentEditableContainer: contentEditableContainer, updateObject: updateObject, experimental: experimental }),
react_1.default.createElement(contentEditable_1.ContentEditableStyled, { key: editMode, className: "contentProxyEditor",
// ref={ref}
ref: setContentEditableContainer, onFocus: onFocus, onBlur: onBlur,
// contentEditable={contentEditable}
contentEditable: editMode === interfaces_1.ContentProxyEditMode.HTML, suppressContentEditableWarning: true }, children)));
}, [
children,
className,
closestInSelection,
contentEditableContainer,
editMode,
experimental,
focused,
newContent,
onBlur,
onFocus,
saveChanges,
updateObject,
]);
return react_1.default.createElement(react_1.default.Fragment, null, contentProxy);
};
exports.default = ContentProxy;
//# sourceMappingURL=index.js.map