UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

71 lines (70 loc) 3.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PeritextView = void 0; const tslib_1 = require("tslib"); const React = tslib_1.__importStar(require("react")); const nano_theme_1 = require("nano-theme"); const constants_1 = require("../constants"); const cursor_1 = require("../../plugins/cursor"); const minimal_1 = require("../../plugins/minimal"); const state_1 = require("../state"); const context_1 = require("./context"); const BlockView_1 = require("./BlockView"); const useBehaviorSubject_1 = require("nice-ui/lib/hooks/useBehaviorSubject"); const events_1 = require("../../../json-crdt-extensions/peritext/events"); (0, nano_theme_1.put)('.' + constants_1.CssClass.Editable, { pos: 'relative', zIndex: 1, out: 0, whiteSpace: 'nowrap', wordWrap: 'break-word', /** @todo Move these to the default theme. */ fontVariantNumeric: 'slashed-zero oldstyle-nums', fontOpticalSizing: 'auto', }); (0, nano_theme_1.put)('.' + constants_1.CssClass.Overlays, { pos: 'relative', zIndex: 2, h: '0px', }); (0, nano_theme_1.put)('.' + constants_1.CssClass.Inline, { whiteSpace: 'pre-wrap', }); exports.PeritextView = React.memo((props) => { const { peritext, plugins: plugins_, onStart: onState } = props; // The `.stop()` is called when the editor unmounts. const stop = React.useRef(void 0); // Plugins provided through props, or a default set of plugins. const plugins = React.useMemo(() => plugins_ ?? [new cursor_1.CursorPlugin(), minimal_1.defaultPlugin], [plugins_]); /** Create the {@link PeritextSurfaceState} state management instance. */ const state = React.useMemo(() => new state_1.PeritextSurfaceState((0, events_1.createEvents)(peritext), plugins), [peritext, plugins]); /** Call `.start()` of {@link PeritextSurfaceState} and setup HTML element. */ const ref = (el) => { if (!el) return; state.el = el; stop.current = state.start(); onState?.(state); }; /** Call `.stop()` of {@link PeritextSurfaceState} when the component unmounts. */ React.useLayoutEffect(() => () => stop.current?.(), []); // Return the final result. return (React.createElement(context_1.context.Provider, { value: state }, React.createElement("div", { className: constants_1.CssClass.Editor }, React.createElement(PeritextViewInner, { div: ref, state: state }), React.createElement("div", { ref: (el) => (state.portalEl = el || void 0), className: constants_1.CssClass.Overlays })))); }); const PeritextViewInner = React.memo((props) => { const { state, div } = props; // Subscribe to re-render events. (0, useBehaviorSubject_1.useBehaviorSubject)(state.render$); // Render the main body of the editor. const block = state.peritext.blocks.root; let children = (React.createElement("div", { ref: div, className: constants_1.CssClass.Editable }, React.createElement(BlockView_1.BlockView, { hash: block.hash, block: block }))); // Run the plugins to decorate our content body. for (const plugin of state.plugins) children = plugin.peritext?.(children, state) ?? children; // Return the final result. return children; });