From aed3c926b2f4ab818107aa30539d2efdfa9bdd6a Mon Sep 17 00:00:00 2001 From: Sandeep-FED <sandeep.ps0124@outlook.com> Date: Sun, 25 May 2025 13:34:39 +0530 Subject: [PATCH] feat[ListItemComments]: make links clickable --- .../listItemComments/common/constants.ts | 1 + .../components/Comments/CommentText.tsx | 46 +++++++++++++++---- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/controls/listItemComments/common/constants.ts b/src/controls/listItemComments/common/constants.ts index c7eacd957..ce9f78964 100644 --- a/src/controls/listItemComments/common/constants.ts +++ b/src/controls/listItemComments/common/constants.ts @@ -1,2 +1,3 @@ export const PHOTO_URL = "/_layouts/15/userphoto.aspx?size=M&accountname="; export const TILE_HEIGHT: number = 70; +export const URL_REGEX = /(https?:\/\/[^\s]+)/g; diff --git a/src/controls/listItemComments/components/Comments/CommentText.tsx b/src/controls/listItemComments/components/Comments/CommentText.tsx index 4b46d239d..f8a981133 100644 --- a/src/controls/listItemComments/components/Comments/CommentText.tsx +++ b/src/controls/listItemComments/components/Comments/CommentText.tsx @@ -3,11 +3,12 @@ import { useContext, useEffect, useState } from "react"; import { Mention } from "./IComment"; import { Text } from "@fluentui/react/lib/Text"; import { LivePersona } from "../../../LivePersona"; -import { AppContext } from "../../common"; -import regexifyString from "regexify-string"; -import { Stack } from "@fluentui/react/lib/Stack"; -import { isArray, isObject } from "lodash"; +import { AppContext, URL_REGEX } from '../../common'; +import regexifyString from 'regexify-string'; +import { Stack } from '@fluentui/react/lib/Stack'; +import { isArray, isObject } from 'lodash'; import he from 'he'; +import { Link } from '@fluentui/react'; export interface ICommentTextProps { text: string; mentions: Mention[]; @@ -46,26 +47,55 @@ export const CommentText: React.FunctionComponent<ICommentTextProps> = ( setCommentText(result); }, []); + const convertTextToLinksAndText = ( + text: string + ): (string | JSX.Element)[] => { + const parts = text.split(URL_REGEX); + return parts.map((part, index) => { + if (part.match(URL_REGEX)) { + return ( + <Link + key={index} + href={part} + target="_blank" + rel="noopener noreferrer" + style={{ color: theme.link }} + > + {part} + </Link> + ); + } + return part; + }); + }; + return ( <> <Stack wrap horizontal horizontalAlign="start" verticalAlign="center"> {isArray(commentText) ? ( - (commentText as any[]).map((el, i) => { // eslint-disable-line @typescript-eslint/no-explicit-any + (commentText as any[]).map((el, i) => { + // eslint-disable-line @typescript-eslint/no-explicit-any if (isObject(el)) { - return <span key={i} style={{ paddingRight: 5 }}>{el}</span>; + return ( + <span key={i} style={{ paddingRight: 5 }}> + {el} + </span> + ); } else { const _el: string = el.trim(); if (_el.length) { return ( <Text style={{ paddingRight: 5 }} variant="small" key={i}> - {he.decode(_el)} + {convertTextToLinksAndText(he.decode(_el))} </Text> ); } } }) ) : ( - <Text variant="small">{he.decode(commentText)}</Text> + <Text variant="small"> + {convertTextToLinksAndText(he.decode(commentText))} + </Text> )} </Stack> </>