json-joy
Version:
Collection of libraries for building collaborative editing apps.
74 lines (73 loc) • 2.62 kB
JavaScript
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;
;