diff --git a/src/components/highlighted-text/HighlightedText.stories.tsx b/src/components/highlighted-text/HighlightedText.stories.tsx new file mode 100644 index 00000000..608cbb1a --- /dev/null +++ b/src/components/highlighted-text/HighlightedText.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { HighlightedText } from "./HighlightedText"; + +const meta: Meta = { + title: "Components/HighlightedText", + component: HighlightedText, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + text: "Lorem test string Test string", + highlight: "TesT", + }, +}; diff --git a/src/components/highlighted-text/HighlightedText.tsx b/src/components/highlighted-text/HighlightedText.tsx new file mode 100644 index 00000000..35b504dd --- /dev/null +++ b/src/components/highlighted-text/HighlightedText.tsx @@ -0,0 +1,35 @@ +import React, { ComponentProps } from "react"; +import { splitTextWithHighlight } from "../../utils"; + +import styles from "./styles/index.module.scss"; + +interface IHighlightedTextProps { + text: string; + highlight?: string; + className?: ComponentProps<"div">["className"]; +} + +export const HighlightedText: React.FC = (props) => { + const { highlight, text, className } = props; + + if (!highlight) { + return text; + } + + const parts = splitTextWithHighlight(text, highlight); + + return ( + + {parts.map((part, index) => { + if (part.toLowerCase() === highlight.toLowerCase()) { + return ( + + {part} + + ); + } + return {part}; + })} + + ); +}; diff --git a/src/components/highlighted-text/index.ts b/src/components/highlighted-text/index.ts new file mode 100644 index 00000000..caa50aa9 --- /dev/null +++ b/src/components/highlighted-text/index.ts @@ -0,0 +1 @@ +export * from "./HighlightedText"; diff --git a/src/components/highlighted-text/styles/index.module.scss b/src/components/highlighted-text/styles/index.module.scss new file mode 100644 index 00000000..ae2769b6 --- /dev/null +++ b/src/components/highlighted-text/styles/index.module.scss @@ -0,0 +1,4 @@ +.highlight_text { + background-color: var(--pv-color-attention-tint-4); + color: var(--pv-color-attention-shade-3); +} diff --git a/src/utils/index.ts b/src/utils/index.ts index da8d5707..2b082df8 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -31,3 +31,13 @@ export function formatBytes(bytes: number, decimals = 2) { return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; } + +export function escapeRegexCharacters(str: string) { + return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + +export function splitTextWithHighlight(text: string, highlight: string) { + const escapedHighlight = escapeRegexCharacters(highlight); + const highlightRegex = new RegExp(`(${escapedHighlight})`, "gi"); + return text.split(highlightRegex); +}