feat(ui): additional social providers to link components (#21716)

The current link component matches only to linkedin, twitter and
facebook.

It is currently missing the x handle. In addition to this, we should
also accomodate for instagram, bluesky and tiktok.

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21716?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Vincent Vu
2026-06-24 20:21:17 +10:00
committed by GitHub
parent d2387430a1
commit 680e4a712b
11 changed files with 297 additions and 105 deletions
@@ -30,9 +30,24 @@ describe('checkUrlType', () => {
expect(checkUrlType('instagram.com/ptcrash')).toBe(LinkType.Instagram);
});
it('should detect TikTok urls', () => {
expect(checkUrlType('https://www.tiktok.com/@twenty')).toBe(
LinkType.TikTok,
);
expect(checkUrlType('tiktok.com/@twenty')).toBe(LinkType.TikTok);
});
it('should detect Bluesky urls', () => {
expect(checkUrlType('https://bsky.app/profile/twenty.bsky.social')).toBe(
LinkType.Bluesky,
);
});
it('should fall back to a generic url type', () => {
expect(checkUrlType('https://example.com')).toBe(LinkType.Url);
expect(checkUrlType('not-a-url')).toBe(LinkType.Url);
expect(checkUrlType('https://instagram.com')).toBe(LinkType.Url);
expect(checkUrlType('https://www.tiktok.com/video/123')).toBe(LinkType.Url);
expect(checkUrlType('https://bsky.app')).toBe(LinkType.Url);
});
});
@@ -7,6 +7,8 @@ describe('isSocialLinkType', () => {
expect(isSocialLinkType(LinkType.Twitter)).toBe(true);
expect(isSocialLinkType(LinkType.Facebook)).toBe(true);
expect(isSocialLinkType(LinkType.Instagram)).toBe(true);
expect(isSocialLinkType(LinkType.TikTok)).toBe(true);
expect(isSocialLinkType(LinkType.Bluesky)).toBe(true);
});
it('should return false for a generic url type', () => {
@@ -1,20 +1,9 @@
import { LinkType } from 'twenty-ui/navigation';
export const checkUrlType = (url: string) => {
if (/^(https?:\/\/)?(www\.)?linkedin\.com\/.+$/.test(url)) {
return LinkType.LinkedIn;
}
if (/^(https?:\/\/)?(www\.)?twitter\.com\/.+$/.test(url)) {
return LinkType.Twitter;
}
if (/^(https?:\/\/)?(www\.)?x\.com\/.+$/.test(url)) {
return LinkType.Twitter;
}
if (/^(https?:\/\/)?(www\.)?facebook\.com\/.+$/.test(url)) {
return LinkType.Facebook;
}
if (/^(https?:\/\/)?(www\.)?instagram\.com\/.+$/.test(url)) {
return LinkType.Instagram;
}
import { LinkType, SOCIAL_LINK_PROVIDERS } from 'twenty-ui/navigation';
return LinkType.Url;
export const checkUrlType = (url: string) => {
const provider = SOCIAL_LINK_PROVIDERS.find((socialLinkProvider) =>
socialLinkProvider.detectPattern.test(url),
);
return provider?.type ?? LinkType.Url;
};
@@ -1,12 +1,6 @@
import { LinkType } from 'twenty-ui/navigation';
// Link types rendered as a social handle (via SocialLink) instead of a plain RoundedLink
const SOCIAL_LINK_TYPES = [
LinkType.LinkedIn,
LinkType.Twitter,
LinkType.Facebook,
LinkType.Instagram,
];
import { type LinkType, SOCIAL_LINK_PROVIDERS } from 'twenty-ui/navigation';
export const isSocialLinkType = (type: LinkType): boolean =>
SOCIAL_LINK_TYPES.includes(type);
SOCIAL_LINK_PROVIDERS.some(
(socialLinkProvider) => socialLinkProvider.type === type,
);