@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
142 lines • 3.4 kB
JavaScript
import React, { Fragment } from 'react';
import InlineLink from "./internal/InlineLink.js";
import CodeEl from "../elements/Code.js";
import { jsx as _jsx } from "react/jsx-runtime";
const Strong = c => _jsx("strong", {
children: c
});
const Em = c => _jsx("em", {
children: c
});
const Code = c => _jsx(CodeEl, {
children: c
});
const Link = (c, href) => _jsx(InlineLink, {
href: href,
rel: "noopener noreferrer",
children: 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
}) => _jsx("br", {}, k()));
const codeRe = /(`[^`]+`)/g;
nodes = replaceInStrings(nodes, codeRe, (m, {
k
}) => [_jsx(Fragment, {
children: code(m[0].slice(1, -1))
}, `c-${k()}`)]);
const linkRe = /\[([^\]]+)\]\(([^)\s]+)\)/g;
nodes = replaceInStrings(nodes, linkRe, (m, {
k
}) => {
const [, label, href] = m;
const children = withFormatting(label, {
br,
strong,
em,
link,
code
});
return [_jsx(Fragment, {
children: link(children, href)
}, `a-${k()}`)];
});
const bareUrlRe = /\b((?:https?:\/\/)[^\s<>()]+)\b/g;
nodes = replaceInStrings(nodes, bareUrlRe, (m, {
k
}) => {
const href = m[1];
return [_jsx(Fragment, {
children: link(href, href)
}, `l-${k()}`)];
});
const boldRe = /\*\*([^*]+)\*\*/g;
nodes = replaceInStrings(nodes, boldRe, (m, {
k
}) => [_jsx(Fragment, {
children: strong(m[1])
}, `b-${k()}`)]);
const italicRe = /_([^_]+)_/g;
nodes = replaceInStrings(nodes, italicRe, (m, {
k
}) => [_jsx(Fragment, {
children: em(m[1])
}, `i-${k()}`)]);
return _jsx(Fragment, {
children: nodes
}, "renderWithFormatting");
}
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) out.push(before);
out.push(...replacer(m, {
i,
k
}));
last = m.index + m[0].length;
if (re.lastIndex === m.index) re.lastIndex++;
}
const tail = n.slice(last);
if (tail) out.push(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) out.push(chunk);
if (idx < parts.length - 1) out.push(_jsx(Fragment, {
children: make({
i,
idx,
k
})
}, k()));
});
return out;
});
}
//# sourceMappingURL=renderWithFormatting.js.map