diff --git a/.changeset/perfect-candles-refuse.md b/.changeset/perfect-candles-refuse.md new file mode 100644 index 0000000000..2b4f02c938 --- /dev/null +++ b/.changeset/perfect-candles-refuse.md @@ -0,0 +1,6 @@ +--- +'@lg-chat/rich-links': minor +'@lg-chat/message': minor +--- + +Add the onLinkClick prop to support callbacks whenever a rich link is clicked diff --git a/chat/message/src/Message/Message.tsx b/chat/message/src/Message/Message.tsx index 852a82ba29..babd840121 100644 --- a/chat/message/src/Message/Message.tsx +++ b/chat/message/src/Message/Message.tsx @@ -49,6 +49,7 @@ export const Message = forwardRef( componentOverrides, links, linksHeading, + onLinkClick, markdownProps, verified, darkMode: darkModeProp, @@ -146,6 +147,7 @@ export const Message = forwardRef( as={componentOverrides?.MessageLinks ?? MessageLinks} headingText={linksHeading} links={links} + onLinkClick={onLinkClick} /> ) : null} {children} diff --git a/chat/message/src/Message/Message.types.ts b/chat/message/src/Message/Message.types.ts index 7da1e45b84..0fb220be39 100644 --- a/chat/message/src/Message/Message.types.ts +++ b/chat/message/src/Message/Message.types.ts @@ -70,6 +70,11 @@ export interface MessageProps * The heading text to display for the links section. */ linksHeading?: string; + + /** + * A callback function that is called when any link is clicked. + */ + onLinkClick?: RichLinkProps['onLinkClick']; } export interface VerificationInfo { diff --git a/chat/message/src/MessageLinks/MessageLinks.tsx b/chat/message/src/MessageLinks/MessageLinks.tsx index c79fe96718..983a23f2ed 100644 --- a/chat/message/src/MessageLinks/MessageLinks.tsx +++ b/chat/message/src/MessageLinks/MessageLinks.tsx @@ -16,6 +16,7 @@ export function MessageLinks({ darkMode: darkModeProp, headingText = 'Related Resources', links, + onLinkClick, ...divProps }: MessageLinksProps) { const { theme } = useDarkMode(darkModeProp); @@ -23,7 +24,7 @@ export function MessageLinks({

{headingText} - +
); } diff --git a/chat/message/src/MessageLinks/MessageLinks.types.ts b/chat/message/src/MessageLinks/MessageLinks.types.ts index 6e0712227b..03cc811923 100644 --- a/chat/message/src/MessageLinks/MessageLinks.types.ts +++ b/chat/message/src/MessageLinks/MessageLinks.types.ts @@ -10,6 +10,11 @@ export interface MessageLinksProps */ headingText?: string; + /** + * A callback function that is called when any link is clicked. + */ + onLinkClick?: RichLinkProps['onLinkClick']; + /** * An list of link data to render in the links section. */ diff --git a/chat/rich-links/src/RichLink/RichLink.spec.tsx b/chat/rich-links/src/RichLink/RichLink.spec.tsx index 47f12ad5aa..ffe9a8d3ca 100644 --- a/chat/rich-links/src/RichLink/RichLink.spec.tsx +++ b/chat/rich-links/src/RichLink/RichLink.spec.tsx @@ -1,9 +1,8 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; -import { RichLinkVariantName } from '../../dist'; - -import { RichLink } from '.'; +import { RichLink, type RichLinkVariantName } from '.'; describe('@lg-chat/rich-links', () => { describe('RichLink', () => { @@ -95,5 +94,46 @@ describe('@lg-chat/rich-links', () => { expect(screen.queryByText('Undefined Variant Link')).toBeInTheDocument(); }); + + it('calls the onLinkClick prop when the link is clicked', () => { + const onLinkClick = jest.fn(); + render( + <> + + Built-in Variant Link + + + Custom Link + + , + ); + const link = screen.getByText('Built-in Variant Link'); + userEvent.click(link); + expect(onLinkClick).toHaveBeenCalledWith({ + href: 'https://mongodb.design/built-in', + children: 'Built-in Variant Link', + variant: 'Website', + }); + + const customLink = screen.getByText('Custom Link'); + userEvent.click(customLink); + expect(onLinkClick).toHaveBeenCalledWith({ + href: 'https://mongodb.design/custom', + children: 'Custom Link', + badgeGlyph: 'ArrowRight', + badgeLabel: 'Custom Label', + badgeColor: 'blue', + }); + }); }); }); diff --git a/chat/rich-links/src/RichLink/RichLink.tsx b/chat/rich-links/src/RichLink/RichLink.tsx index 3caa71fe1a..a6d52b25fc 100644 --- a/chat/rich-links/src/RichLink/RichLink.tsx +++ b/chat/rich-links/src/RichLink/RichLink.tsx @@ -18,7 +18,7 @@ import { RichLinkBadge } from './RichLinkBadge'; import { richLinkVariants } from './richLinkVariants'; export const RichLink = forwardRef( - ({ darkMode: darkModeProp, ...props }, ref) => { + ({ darkMode: darkModeProp, onLinkClick, ...props }, ref) => { const { darkMode, theme } = useDarkMode(darkModeProp); const richLinkVariantProps = @@ -64,6 +64,7 @@ export const RichLink = forwardRef( [imageBackgroundStyles(imageUrl ?? '')]: showImageBackground, })} {...conditionalProps} + onClick={() => onLinkClick?.(props)} > {children} diff --git a/chat/rich-links/src/RichLink/RichLink.types.ts b/chat/rich-links/src/RichLink/RichLink.types.ts index 9ad7a1c183..37682f951d 100644 --- a/chat/rich-links/src/RichLink/RichLink.types.ts +++ b/chat/rich-links/src/RichLink/RichLink.types.ts @@ -15,6 +15,11 @@ export interface BaseRichLinkProps * A URL for the background image of the rich link */ imageUrl?: string; + + /** + * A callback function that is called when the link is clicked. + */ + onLinkClick?: (props: Omit) => void; } export interface RichLinkVariantControlProps { diff --git a/chat/rich-links/src/RichLinksArea/RichLinksArea.tsx b/chat/rich-links/src/RichLinksArea/RichLinksArea.tsx index cbd5e71712..c530cb7f30 100644 --- a/chat/rich-links/src/RichLinksArea/RichLinksArea.tsx +++ b/chat/rich-links/src/RichLinksArea/RichLinksArea.tsx @@ -13,6 +13,7 @@ import { type RichLinksAreaProps } from './RichLinksArea.types'; export function RichLinksArea({ links, darkMode: darkModeProp, + onLinkClick, ...props }: RichLinksAreaProps) { const { darkMode } = useDarkMode(darkModeProp); @@ -20,7 +21,13 @@ export function RichLinksArea({
{links.map(richLinkProps => { - return ; + return ( + onLinkClick?.(richLinkProps)} + {...richLinkProps} + /> + ); })}
diff --git a/chat/rich-links/src/RichLinksArea/RichLinksArea.types.ts b/chat/rich-links/src/RichLinksArea/RichLinksArea.types.ts index cb8ef2e600..249329a402 100644 --- a/chat/rich-links/src/RichLinksArea/RichLinksArea.types.ts +++ b/chat/rich-links/src/RichLinksArea/RichLinksArea.types.ts @@ -7,4 +7,9 @@ export interface RichLinksAreaProps extends HTMLElementProps<'div', never>, DarkModeProps { links: Array; + + /** + * A callback function that is called when any link is clicked. + */ + onLinkClick?: RichLinkProps['onLinkClick']; }