Port over linkifyJS to shared-components. (#32731)

* Port over linkifyJS to shared-components.

* Drop rubbish

* update lock

* quickfix test

* drop group id

* Modernize tests

* Remove stories that aren't in use.

* Complete working version

* Add copyright

* tidy up

* update lock

* Update snaps

* update snap

* undo change

* remove unused

* More test updates

* fix typo

* fix margin on preview

* move margin block

* snapupdate

* prettier

* cleanup a test mistake

* Fixup sonar issues

* Don't expose linkifyjs to applications, just provide helper functions.

* Add story for documentation.

* remove $

* Use a const

* typo

* cleanup var name

* remove console line

* Changes checkpoint

* Convert to context

* Revert unrelated change.

* more cleanup

* Add a test to cover ignoring incoming data elements

* Make tests happy

* Update tests for LinkedText

* Underlines!

* fix lock

* remove unused linkify packages

* import move

* Remove mod to remove underline

* undo

* fix snap

* another snapshot fix

* Tidy up based on review.

* fix story

* Pass in args
This commit is contained in:
Will Hunt
2026-03-12 15:54:01 +00:00
committed by GitHub
parent d38eb4fdb4
commit c02db4ebb8
44 changed files with 1508 additions and 839 deletions
@@ -28,7 +28,7 @@ import { TooltipProvider } from "@vector-im/compound-web";
// what-input helps improve keyboard accessibility
import "what-input";
import sanitizeHtml from "sanitize-html";
import { I18nContext } from "@element-hq/web-shared-components";
import { I18nContext, LinkedTextContext, LinkedText } from "@element-hq/web-shared-components";
import { LockSolidIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
import PosthogTrackers from "../../PosthogTrackers";
@@ -125,7 +125,7 @@ import { viewUserDeviceSettings } from "../../actions/handlers/viewUserDeviceSet
import GenericToast from "../views/toasts/GenericToast";
import RovingSpotlightDialog from "../views/dialogs/spotlight/SpotlightDialog";
import { findDMForUser } from "../../utils/dm/findDMForUser";
import { getHtmlText, Linkify } from "../../HtmlUtils";
import { getHtmlText } from "../../HtmlUtils";
import { NotificationLevel } from "../../stores/notifications/NotificationLevel";
import { type UserTab } from "../views/dialogs/UserTab";
import { shouldSkipSetupEncryption } from "../../utils/crypto/shouldSkipSetupEncryption";
@@ -139,7 +139,7 @@ import { setTheme } from "../../theme";
import { type OpenForwardDialogPayload } from "../../dispatcher/payloads/OpenForwardDialogPayload";
import { ShareFormat, type SharePayload } from "../../dispatcher/payloads/SharePayload";
import Markdown from "../../Markdown";
import { sanitizeHtmlParams } from "../../Linkify";
import { LinkedTextConfiguration, sanitizeHtmlParams } from "../../Linkify";
import { isOnlyAdmin } from "../../utils/membership";
import { ModuleApi } from "../../modules/Api.ts";
@@ -1458,7 +1458,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
key,
title: userNotice.title,
props: {
description: <Linkify>{userNotice.description}</Linkify>,
description: <LinkedText>{userNotice.description}</LinkedText>,
primaryLabel: _t("action|ok"),
onPrimaryClick: () => {
ToastStore.sharedInstance().dismissToast(key);
@@ -2291,7 +2291,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
<ErrorBoundary>
<I18nContext.Provider value={ModuleApi.instance.i18n}>
<SDKContext.Provider value={this.stores}>
<TooltipProvider>{view}</TooltipProvider>
<LinkedTextContext.Provider value={LinkedTextConfiguration}>
<TooltipProvider>{view}</TooltipProvider>
</LinkedTextContext.Provider>
</SDKContext.Provider>
</I18nContext.Provider>
</ErrorBoundary>
@@ -41,6 +41,7 @@ import { sortBy, uniqBy } from "lodash";
import { logger } from "matrix-js-sdk/src/logger";
import { KnownMembership, type SpaceChildEventContent } from "matrix-js-sdk/src/types";
import { ChevronDownIcon, CheckIcon } from "@vector-im/compound-design-tokens/assets/web/icons";
import { LinkedText } from "@element-hq/web-shared-components";
import defaultDispatcher from "../../dispatcher/dispatcher";
import { _t } from "../../languageHandler";
@@ -55,7 +56,7 @@ import InfoTooltip from "../views/elements/InfoTooltip";
import TextWithTooltip from "../views/elements/TextWithTooltip";
import { useStateToggle } from "../../hooks/useStateToggle";
import { getChildOrder } from "../../stores/spaces/SpaceStore";
import { Linkify, topicToHtml } from "../../HtmlUtils";
import { topicToHtml } from "../../HtmlUtils";
import { useDispatcher } from "../../hooks/useDispatcher";
import { Action } from "../../dispatcher/actions";
import { type IState, RovingTabIndexProvider, useRovingTabIndex } from "../../accessibility/RovingTabIndex";
@@ -233,20 +234,12 @@ const Tile: React.FC<ITileProps> = ({
let topicSection: ReactNode | undefined;
if (topic) {
// prevent clicks on links from bubbling up to the room tile
topicSection = (
<Linkify
options={{
attributes: {
onClick(ev: MouseEvent) {
// prevent clicks on links from bubbling up to the room tile
ev.stopPropagation();
},
},
}}
>
<LinkedText onLinkClick={(ev) => ev.stopPropagation()}>
{" · "}
{topic}
</Linkify>
</LinkedText>
);
}