UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

1 lines 5.75 kB
{"version":3,"file":"Highlight.cjs","names":["polymorphicFactory","useProps","foldAccents","highlighter","Text","Mark"],"sources":["../../../src/components/Highlight/Highlight.tsx"],"sourcesContent":["import {\n MantineColor,\n MantineTheme,\n polymorphicFactory,\n PolymorphicFactory,\n useProps,\n} from '../../core';\nimport { Mark } from '../Mark';\nimport { Text, TextProps, TextStylesNames, TextVariant } from '../Text';\nimport { foldAccents, highlighter } from './highlighter/highlighter';\n\nexport interface HighlightTerm {\n /** Text to highlight */\n text: string;\n\n /** Background color for this specific term. Key of `theme.colors` or any valid CSS color */\n color?: MantineColor | string;\n}\n\nexport interface HighlightProps extends Omit<TextProps, 'color'> {\n /**\n * Substring(s) to highlight in `children`. Can be:\n * - string: single term\n * - string[]: multiple terms with same color\n * - HighlightTerm[]: multiple terms with custom colors per term\n *\n * - Matching is case-insensitive and accent-insensitive by default, use `caseInsensitive` and `accentInsensitive` props to control this behavior\n * - Regex special characters are automatically escaped\n * - When multiple substrings are provided, longer matches take precedence\n * - Empty strings and whitespace-only strings are ignored\n */\n highlight: string | string[] | HighlightTerm[];\n\n /**\n * Default background color for all highlighted text.\n * Key of `theme.colors` or any valid CSS color, passed to `Mark` component.\n * Can be overridden per term when using HighlightTerm objects.\n * @default 'yellow'\n */\n color?: MantineColor | string;\n\n /** Styles applied to `mark` elements */\n highlightStyles?: React.CSSProperties | ((theme: MantineTheme) => React.CSSProperties);\n\n /** String in which to highlight substrings */\n children: string;\n\n /**\n * Only match whole words (adds word boundaries to regex).\n * When enabled, 'the' will not match 'there'.\n * @default false\n */\n wholeWord?: boolean;\n\n /**\n * Perform case-insensitive matching.\n * @default true\n */\n caseInsensitive?: boolean;\n\n /**\n * Perform accent-insensitive matching.\n * When enabled cafe will match cafe, café, cafè, etc.\n * @default true\n */\n accentInsensitive?: boolean;\n}\n\nexport type HighlightFactory = PolymorphicFactory<{\n props: HighlightProps;\n defaultRef: HTMLDivElement;\n defaultComponent: 'div';\n stylesNames: TextStylesNames;\n variant: TextVariant;\n}>;\n\nconst defaultProps = {\n color: 'yellow',\n wholeWord: false,\n caseInsensitive: true,\n accentInsensitive: true,\n} satisfies Partial<HighlightProps>;\n\nexport const Highlight = polymorphicFactory<HighlightFactory>((_props) => {\n const {\n unstyled,\n children,\n highlight,\n highlightStyles,\n color,\n wholeWord,\n caseInsensitive,\n accentInsensitive,\n ...others\n } = useProps('Highlight', defaultProps, _props);\n\n const isTermArray = Array.isArray(highlight) && typeof highlight[0] === 'object';\n const colorMap = new Map<string, string>();\n\n const normalizeKey = (s: string) => {\n let key = s;\n if (caseInsensitive) {\n key = key.toLowerCase();\n }\n if (accentInsensitive) {\n key = foldAccents(key);\n }\n return key;\n };\n\n let highlightStrings: string[];\n if (isTermArray) {\n highlightStrings = (highlight as HighlightTerm[]).map((term) => {\n if (term.color) {\n colorMap.set(normalizeKey(term.text), term.color);\n }\n return term.text;\n });\n } else if (Array.isArray(highlight)) {\n highlightStrings = highlight as string[];\n } else {\n highlightStrings = [highlight as string];\n }\n\n const highlightChunks = highlighter(children, highlightStrings, {\n wholeWord,\n caseInsensitive,\n accentInsensitive,\n });\n\n return (\n <Text unstyled={unstyled} {...others} __staticSelector=\"Highlight\">\n {highlightChunks.map(({ chunk, highlighted }, i) =>\n highlighted ? (\n <Mark\n unstyled={unstyled}\n key={i}\n color={colorMap.get(normalizeKey(chunk)) || color}\n style={highlightStyles}\n data-highlight={chunk}\n >\n {chunk}\n </Mark>\n ) : (\n <span key={i}>{chunk}</span>\n )\n )}\n </Text>\n );\n});\n\nHighlight.classes = Text.classes;\nHighlight.displayName = '@mantine/core/Highlight';\n\nexport namespace Highlight {\n export type Props = HighlightProps;\n export type Factory = HighlightFactory;\n export type Term = HighlightTerm;\n}\n"],"mappings":";;;;;;;;;AA4EA,MAAM,eAAe;CACnB,OAAO;CACP,WAAW;CACX,iBAAiB;CACjB,mBAAmB;AACrB;AAEA,MAAa,YAAYA,4BAAAA,oBAAsC,WAAW;CACxE,MAAM,EACJ,UACA,UACA,WACA,iBACA,OACA,WACA,iBACA,mBACA,GAAG,WACDC,kBAAAA,SAAS,aAAa,cAAc,MAAM;CAE9C,MAAM,cAAc,MAAM,QAAQ,SAAS,KAAK,OAAO,UAAU,OAAO;CACxE,MAAM,2BAAW,IAAI,IAAoB;CAEzC,MAAM,gBAAgB,MAAc;EAClC,IAAI,MAAM;EACV,IAAI,iBACF,MAAM,IAAI,YAAY;EAExB,IAAI,mBACF,MAAMC,oBAAAA,YAAY,GAAG;EAEvB,OAAO;CACT;CAEA,IAAI;CACJ,IAAI,aACF,mBAAoB,UAA8B,KAAK,SAAS;EAC9D,IAAI,KAAK,OACP,SAAS,IAAI,aAAa,KAAK,IAAI,GAAG,KAAK,KAAK;EAElD,OAAO,KAAK;CACd,CAAC;MACI,IAAI,MAAM,QAAQ,SAAS,GAChC,mBAAmB;MAEnB,mBAAmB,CAAC,SAAmB;CAGzC,MAAM,kBAAkBC,oBAAAA,YAAY,UAAU,kBAAkB;EAC9D;EACA;EACA;CACF,CAAC;CAED,OACE,iBAAA,GAAA,kBAAA,KAACC,aAAAA,MAAD;EAAgB;EAAU,GAAI;EAAQ,kBAAiB;YACpD,gBAAgB,KAAK,EAAE,OAAO,eAAe,MAC5C,cACE,iBAAA,GAAA,kBAAA,KAACC,aAAAA,MAAD;GACY;GAEV,OAAO,SAAS,IAAI,aAAa,KAAK,CAAC,KAAK;GAC5C,OAAO;GACP,kBAAgB;aAEf;EACG,GANC,CAMD,IAEN,iBAAA,GAAA,kBAAA,KAAC,QAAD,EAAA,UAAe,MAAY,GAAhB,CAAgB,CAE/B;CACI,CAAA;AAEV,CAAC;AAED,UAAU,UAAUD,aAAAA,KAAK;AACzB,UAAU,cAAc"}