@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
1 lines • 5.59 kB
Source Map (JSON)
{"version":3,"file":"highlighter.cjs","names":[],"sources":["../../../../src/components/Highlight/highlighter/highlighter.ts"],"sourcesContent":["function escapeRegex(value: string) {\n return value.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');\n}\n\nexport function foldAccents(text: string): string {\n return text.normalize('NFD').replace(/\\p{M}/gu, '');\n}\n\nfunction foldAccentsWithMap(text: string): { folded: string; map: number[] } {\n let folded = '';\n const map: number[] = [];\n let i = 0;\n\n while (i < text.length) {\n const cp = text.codePointAt(i)!;\n const cpStr = String.fromCodePoint(cp);\n const foldedCp = foldAccents(cpStr);\n for (let j = 0; j < foldedCp.length; j += 1) {\n map.push(i);\n }\n folded += foldedCp;\n i += cpStr.length;\n }\n\n map.push(text.length);\n return { folded, map };\n}\n\nfunction getAccentInsensitiveChunks(value: string, re: RegExp): HighlightChunk[] {\n const { folded, map } = foldAccentsWithMap(value);\n const chunks: HighlightChunk[] = [];\n let lastOrigEnd = 0;\n let match: RegExpExecArray | null;\n\n while ((match = re.exec(folded)) !== null) {\n const foldedStart = match.index;\n const foldedEnd = foldedStart + match[0].length;\n const origStart = map[foldedStart];\n const origEnd = map[foldedEnd];\n\n if (origStart > lastOrigEnd) {\n chunks.push({ chunk: value.slice(lastOrigEnd, origStart), highlighted: false });\n }\n chunks.push({ chunk: value.slice(origStart, origEnd), highlighted: true });\n lastOrigEnd = origEnd;\n\n if (match[0].length === 0) {\n re.lastIndex += 1;\n }\n }\n\n if (lastOrigEnd < value.length) {\n chunks.push({ chunk: value.slice(lastOrigEnd), highlighted: false });\n }\n\n return chunks.filter(({ chunk }) => chunk);\n}\n\nexport interface HighlightChunk {\n chunk: string;\n highlighted: boolean;\n color?: string;\n}\n\nexport interface HighlighterOptions {\n wholeWord?: boolean;\n caseInsensitive?: boolean;\n accentInsensitive?: boolean;\n}\n\nexport function highlighter(\n value: string,\n _highlight: string | string[],\n options: HighlighterOptions = {}\n): HighlightChunk[] {\n if (_highlight == null) {\n return [{ chunk: value, highlighted: false }];\n }\n\n const { wholeWord = false, caseInsensitive = true, accentInsensitive = true } = options;\n\n const prepareTerm = (term: string) =>\n accentInsensitive ? foldAccents(escapeRegex(term)) : escapeRegex(term);\n\n const highlight = Array.isArray(_highlight)\n ? _highlight.map(prepareTerm)\n : prepareTerm(_highlight);\n\n const shouldHighlight = Array.isArray(highlight)\n ? highlight.filter((part) => part.trim().length > 0).length > 0\n : highlight.trim() !== '';\n\n if (!shouldHighlight) {\n return [{ chunk: value, highlighted: false }];\n }\n\n const matcher =\n typeof highlight === 'string'\n ? highlight.trim()\n : highlight\n .filter((part) => part.trim().length !== 0)\n .map((part) => part.trim())\n .sort((a, b) => b.length - a.length)\n .join('|');\n\n const pattern = wholeWord\n ? `(?<![\\\\p{L}\\\\p{N}_])(${matcher})(?![\\\\p{L}\\\\p{N}_])`\n : `(${matcher})`;\n const flags = ['g', caseInsensitive ? 'i' : '', wholeWord ? 'u' : ''].join('');\n const re = new RegExp(pattern, flags);\n\n if (accentInsensitive) {\n return getAccentInsensitiveChunks(value, re);\n }\n\n return value\n .split(re)\n .map((part, index) => ({ chunk: part, highlighted: index % 2 === 1 }))\n .filter(({ chunk }) => chunk);\n}\n"],"mappings":";;AAAA,SAAS,YAAY,OAAe;CAClC,OAAO,MAAM,QAAQ,uBAAuB,MAAM;AACpD;AAEA,SAAgB,YAAY,MAAsB;CAChD,OAAO,KAAK,UAAU,KAAK,EAAE,QAAQ,WAAW,EAAE;AACpD;AAEA,SAAS,mBAAmB,MAAiD;CAC3E,IAAI,SAAS;CACb,MAAM,MAAgB,CAAC;CACvB,IAAI,IAAI;CAER,OAAO,IAAI,KAAK,QAAQ;EACtB,MAAM,KAAK,KAAK,YAAY,CAAC;EAC7B,MAAM,QAAQ,OAAO,cAAc,EAAE;EACrC,MAAM,WAAW,YAAY,KAAK;EAClC,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,GACxC,IAAI,KAAK,CAAC;EAEZ,UAAU;EACV,KAAK,MAAM;CACb;CAEA,IAAI,KAAK,KAAK,MAAM;CACpB,OAAO;EAAE;EAAQ;CAAI;AACvB;AAEA,SAAS,2BAA2B,OAAe,IAA8B;CAC/E,MAAM,EAAE,QAAQ,QAAQ,mBAAmB,KAAK;CAChD,MAAM,SAA2B,CAAC;CAClC,IAAI,cAAc;CAClB,IAAI;CAEJ,QAAQ,QAAQ,GAAG,KAAK,MAAM,OAAO,MAAM;EACzC,MAAM,cAAc,MAAM;EAC1B,MAAM,YAAY,cAAc,MAAM,GAAG;EACzC,MAAM,YAAY,IAAI;EACtB,MAAM,UAAU,IAAI;EAEpB,IAAI,YAAY,aACd,OAAO,KAAK;GAAE,OAAO,MAAM,MAAM,aAAa,SAAS;GAAG,aAAa;EAAM,CAAC;EAEhF,OAAO,KAAK;GAAE,OAAO,MAAM,MAAM,WAAW,OAAO;GAAG,aAAa;EAAK,CAAC;EACzE,cAAc;EAEd,IAAI,MAAM,GAAG,WAAW,GACtB,GAAG,aAAa;CAEpB;CAEA,IAAI,cAAc,MAAM,QACtB,OAAO,KAAK;EAAE,OAAO,MAAM,MAAM,WAAW;EAAG,aAAa;CAAM,CAAC;CAGrE,OAAO,OAAO,QAAQ,EAAE,YAAY,KAAK;AAC3C;AAcA,SAAgB,YACd,OACA,YACA,UAA8B,CAAC,GACb;CAClB,IAAI,cAAc,MAChB,OAAO,CAAC;EAAE,OAAO;EAAO,aAAa;CAAM,CAAC;CAG9C,MAAM,EAAE,YAAY,OAAO,kBAAkB,MAAM,oBAAoB,SAAS;CAEhF,MAAM,eAAe,SACnB,oBAAoB,YAAY,YAAY,IAAI,CAAC,IAAI,YAAY,IAAI;CAEvE,MAAM,YAAY,MAAM,QAAQ,UAAU,IACtC,WAAW,IAAI,WAAW,IAC1B,YAAY,UAAU;CAM1B,IAAI,EAJoB,MAAM,QAAQ,SAAS,IAC3C,UAAU,QAAQ,SAAS,KAAK,KAAK,EAAE,SAAS,CAAC,EAAE,SAAS,IAC5D,UAAU,KAAK,MAAM,KAGvB,OAAO,CAAC;EAAE,OAAO;EAAO,aAAa;CAAM,CAAC;CAG9C,MAAM,UACJ,OAAO,cAAc,WACjB,UAAU,KAAK,IACf,UACG,QAAQ,SAAS,KAAK,KAAK,EAAE,WAAW,CAAC,EACzC,KAAK,SAAS,KAAK,KAAK,CAAC,EACzB,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EAClC,KAAK,GAAG;CAEjB,MAAM,UAAU,YACZ,wBAAwB,QAAQ,wBAChC,IAAI,QAAQ;CAChB,MAAM,QAAQ;EAAC;EAAK,kBAAkB,MAAM;EAAI,YAAY,MAAM;CAAE,EAAE,KAAK,EAAE;CAC7E,MAAM,KAAK,IAAI,OAAO,SAAS,KAAK;CAEpC,IAAI,mBACF,OAAO,2BAA2B,OAAO,EAAE;CAG7C,OAAO,MACJ,MAAM,EAAE,EACR,KAAK,MAAM,WAAW;EAAE,OAAO;EAAM,aAAa,QAAQ,MAAM;CAAE,EAAE,EACpE,QAAQ,EAAE,YAAY,KAAK;AAChC"}