@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
151 lines (150 loc) • 4.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = renderWithFormatting;
var _push = _interopRequireDefault(require("core-js-pure/stable/instance/push.js"));
var _react = _interopRequireWildcard(require("react"));
var _InlineLink = _interopRequireDefault(require("./internal/InlineLink.js"));
var _Code = _interopRequireDefault(require("../elements/Code.js"));
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const Strong = c => (0, _jsxRuntime.jsx)("strong", {
children: c
});
const Em = c => (0, _jsxRuntime.jsx)("em", {
children: c
});
const Code = c => (0, _jsxRuntime.jsx)(_Code.default, {
children: c
});
const Link = (c, href) => (0, _jsxRuntime.jsx)(_InlineLink.default, {
href: href,
rel: "noopener noreferrer",
children: c
});
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
}) => (0, _jsxRuntime.jsx)("br", {}, k()));
const codeRe = /(`[^`]+`)/g;
nodes = replaceInStrings(nodes, codeRe, (m, {
k
}) => [(0, _jsxRuntime.jsx)(_react.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 [(0, _jsxRuntime.jsx)(_react.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 [(0, _jsxRuntime.jsx)(_react.Fragment, {
children: link(href, href)
}, `l-${k()}`)];
});
const boldRe = /\*\*([^*]+)\*\*/g;
nodes = replaceInStrings(nodes, boldRe, (m, {
k
}) => [(0, _jsxRuntime.jsx)(_react.Fragment, {
children: strong(m[1])
}, `b-${k()}`)]);
const italicRe = /_([^_]+)_/g;
nodes = replaceInStrings(nodes, italicRe, (m, {
k
}) => [(0, _jsxRuntime.jsx)(_react.Fragment, {
children: em(m[1])
}, `i-${k()}`)]);
return (0, _jsxRuntime.jsx)(_react.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) (0, _push.default)(out).call(out, before);
(0, _push.default)(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) (0, _push.default)(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) (0, _push.default)(out).call(out, chunk);
if (idx < parts.length - 1) (0, _push.default)(out).call(out, (0, _jsxRuntime.jsx)(_react.Fragment, {
children: make({
i,
idx,
k
})
}, k()));
});
return out;
});
}
//# sourceMappingURL=renderWithFormatting.js.map