"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;
});
//# sourceMappingURL=PeritextView.js.map