UNPKG

@intl-t/react

Version:

A Fully-Typed Object-Based i18n Translation Library for React

54 lines (53 loc) 1.9 kB
import { createElement } from "react"; const regex = /<(\w+)([^<>/]+)?(?:\/\s*>|>(?:(.*)<\s*\/\s*\1\s*>)?)/gm; const attributesRegex = /(\w+)(?:=(\w+|".*?"|'.*?'|{(.+?)}))?/g; export const Chunk = ({ children, tagName, value, key, tagAttributes: _a, tagContent: _c, ...props }) => { if (value) return String(value); return createElement(tagName, { key, ...props }, children); }; export function injectReactChunks(content = "", variables = {}) { if (!content || !content.includes("<")) return content; const matches = [...content.matchAll(regex)]; if (!matches.length) return content; const elements = []; matches.forEach(match => { const [tag, tagName, tagAttributes, tagContent] = match; const props = { tagName, tagContent, tagAttributes, key: elements.length, children: injectReactChunks(tagContent, variables), }; if (tagAttributes?.trim()) [...tagAttributes.matchAll(attributesRegex)].forEach(match => { let [, key, value, json = value] = match; try { props[key] = JSON.parse(json); } catch { props[key] = value; } }); let element; try { element = (variables[tagName] || Chunk)(props) ?? null; } catch { props.value = variables[tagName]; element = Chunk(props) ?? null; } const [start, ...end] = content.split(tag); if (start) elements.push(start); elements.push(element); content = end.length > 1 ? end.join(tag) : end[0]; }); if (content) elements.push(content); return elements.length > 1 ? elements : elements[0]; } export { injectReactChunks as injectReactChunk };