@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
137 lines • 3.67 kB
JavaScript
import _pushInstanceProperty from "core-js-pure/stable/instance/push.js";
import React, { Fragment } from 'react';
import InlineLink from "./internal/InlineLink.js";
import CodeEl from "../elements/Code.js";
const Strong = c => React.createElement("strong", null, c);
const Em = c => React.createElement("em", null, c);
const Code = c => React.createElement(CodeEl, null, c);
const Link = (c, href) => React.createElement(InlineLink, {
href: href,
rel: "noopener noreferrer"
}, c);
export default function renderWithFormatting(text, {
br = '{br}',
strong = Strong,
em = Em,
link = Link,
code = Code
} = {}) {
if (typeof text === 'string') {
const HAS_MARKERS_RE = /(`[^`]+`|\[[^\]]+\]\([^)\s]+\)|\bhttps?:\/\/[^\s<>()]+|\*\*[^*]+\*\*|_[^_]+_)/;
const hasFormatting = br && text.includes(br) || HAS_MARKERS_RE.test(text);
if (!hasFormatting) {
return text;
}
}
return withFormatting(text, {
strong,
em,
br,
link,
code
});
}
function withFormatting(text, {
br,
strong,
em,
link,
code
}) {
let nodes = Array.isArray(text) ? text : [text];
nodes = splitToken(nodes, br, ({
k
}) => React.createElement("br", {
key: k()
}));
const codeRe = /(`[^`]+`)/g;
nodes = replaceInStrings(nodes, codeRe, (m, {
k
}) => [React.createElement(Fragment, {
key: `c-${k()}`
}, code(m[0].slice(1, -1)))]);
const linkRe = /\[([^\]]+)\]\(([^)\s]+)\)/g;
nodes = replaceInStrings(nodes, linkRe, (m, {
k
}) => {
const [, label, href] = m;
const children = withFormatting(label, {
br,
strong,
em,
link,
code
});
return [React.createElement(Fragment, {
key: `a-${k()}`
}, link(children, href))];
});
const bareUrlRe = /\b((?:https?:\/\/)[^\s<>()]+)\b/g;
nodes = replaceInStrings(nodes, bareUrlRe, (m, {
k
}) => {
const href = m[1];
return [React.createElement(Fragment, {
key: `l-${k()}`
}, link(href, href))];
});
const boldRe = /\*\*([^*]+)\*\*/g;
nodes = replaceInStrings(nodes, boldRe, (m, {
k
}) => [React.createElement(Fragment, {
key: `b-${k()}`
}, strong(m[1]))]);
const italicRe = /_([^_]+)_/g;
nodes = replaceInStrings(nodes, italicRe, (m, {
k
}) => [React.createElement(Fragment, {
key: `i-${k()}`
}, em(m[1]))]);
return React.createElement(Fragment, {
key: "renderWithFormatting"
}, nodes);
}
function replaceInStrings(nodes, re, replacer) {
let key = 0;
const k = () => String(key++);
return nodes.flatMap((n, i) => {
if (typeof n !== 'string') return [n];
const out = [];
let last = 0;
let m;
while ((m = re.exec(n)) !== null) {
const before = n.slice(last, m.index);
if (before) _pushInstanceProperty(out).call(out, before);
_pushInstanceProperty(out).call(out, ...replacer(m, {
i,
k
}));
last = m.index + m[0].length;
if (re.lastIndex === m.index) re.lastIndex++;
}
const tail = n.slice(last);
if (tail) _pushInstanceProperty(out).call(out, tail);
return out;
});
}
function splitToken(nodes, token, make) {
let key = 0;
const k = () => String(key++);
return nodes.flatMap((n, i) => {
if (typeof n !== 'string') return [n];
const parts = n.split(token);
const out = [];
parts.forEach((chunk, idx) => {
if (chunk) _pushInstanceProperty(out).call(out, chunk);
if (idx < parts.length - 1) _pushInstanceProperty(out).call(out, React.createElement(Fragment, {
key: k()
}, make({
i,
idx,
k
})));
});
return out;
});
}
//# sourceMappingURL=renderWithFormatting.js.map