UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

74 lines (73 loc) 2.62 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InlineView = 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 context_1 = require("./context"); (0, nano_theme_1.put)('.' + constants_1.CssClass.Inline, { /** * Font *kerning* is the variable distance between every pair of characters. * It is adjusted to make the text more readable. This disables it, so that * there is always the same distance between characters. * * Useful because, while moving the cursor the characters can be arbitrarily * grouped into <span> elements, the distance between them should be * consistent to avoid layout shifts. Otherwise, there is a text shift when * moving the cursor. For example, consider: * * ```jsx * <span>Word</span> * ``` * * vs. * * ```jsx * <span>W</span><span>ord</span> * ``` * * The kerning between letters "W" and "o" changes and results in a shift, if * this property is not set. */ fontKerning: 'none', /** * Similar to `fontKerning`, but for ligatures. Ligatures are special glyphs * that combine two or more characters into a single glyph. We disable them * so that the text is more visually predictable. */ fontVariantLigatures: 'none', }); /** @todo Add ability to compute `.hash` for {@link Inline} nodes and use for memoization. */ const InlineView = (props) => { const { inline } = props; const ctx = (0, context_1.usePeritext)(); const { plugins, dom } = ctx; const ref = React.useRef(null); const text = inline.text(); const span = ref.current; if (span) span[constants_1.ElementAttr.InlineOffset] = inline; let attr = { className: constants_1.CssClass.Inline, ref: (span) => { const inlines = dom.inlines; const start = inline.start; ref.current = span; if (span) { span[constants_1.ElementAttr.InlineOffset] = inline; inlines.set(start, span); } else { inlines.del(start); } }, }; for (const map of plugins) attr = map.text?.(attr, inline, ctx) ?? attr; let children = React.createElement("span", { ...attr }, text); for (const map of plugins) children = map.inline?.(props, children) ?? children; return children; }; exports.InlineView = InlineView;