From 15817cffc523066b87ba8ed507b8b4ebacac9557 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jun 2025 11:36:02 +0100 Subject: [PATCH 01/30] Very first pass at shared component views Turn the trivial TextualEvent into a shared component with a separate view model for element web. Args to view model will probably change to be more specific and VM typer needs abstracting out into an interface, but should give the general idea. --- src/events/EventTileFactory.tsx | 8 ++- .../TextualEvent/TextualEvent.stories.tsx | 0 .../TextualEvent/TextualEvent.test.tsx | 0 .../event-tiles/TextualEvent/TextualEvent.tsx | 21 +++++++ .../event-tiles/TextualEvent/index.ts | 8 +++ .../event-tiles/TextualEventViewModel.ts | 57 +++++++++++++++++++ 6 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx create mode 100644 src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx create mode 100644 src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx create mode 100644 src/shared-components/event-tiles/TextualEvent/index.ts create mode 100644 src/viewmodels/event-tiles/TextualEventViewModel.ts diff --git a/src/events/EventTileFactory.tsx b/src/events/EventTileFactory.tsx index 0d91ded160f..b771033a67e 100644 --- a/src/events/EventTileFactory.tsx +++ b/src/events/EventTileFactory.tsx @@ -26,7 +26,6 @@ import { TimelineRenderingType } from "../contexts/RoomContext"; import MessageEvent from "../components/views/messages/MessageEvent"; import LegacyCallEvent from "../components/views/messages/LegacyCallEvent"; import { CallEvent } from "../components/views/messages/CallEvent"; -import TextualEvent from "../components/views/messages/TextualEvent"; import EncryptionEvent from "../components/views/messages/EncryptionEvent"; import { RoomPredecessorTile } from "../components/views/messages/RoomPredecessorTile"; import RoomAvatarEvent from "../components/views/messages/RoomAvatarEvent"; @@ -44,6 +43,8 @@ import { shouldDisplayAsBeaconTile } from "../utils/beacon/timeline"; import { ElementCall } from "../models/Call"; import { type IBodyProps } from "../components/views/messages/IBodyProps"; import ModuleApi from "../modules/Api"; +import { TextualEventViewModel } from "../viewmodels/event-tiles/TextualEventViewModel"; +import { TextualEvent } from "../shared-components/event-tiles/TextualEvent"; // Subset of EventTile's IProps plus some mixins export interface EventTileTypeProps @@ -77,7 +78,10 @@ const LegacyCallEventFactory: Factory ); const CallEventFactory: Factory = (ref, props) => ; -export const TextualEventFactory: Factory = (ref, props) => ; +export const TextualEventFactory: Factory = (ref, props) => { + const vm = new TextualEventViewModel(props); + return ; +}; const VerificationReqFactory: Factory = (_ref, props) => ; const HiddenEventFactory: Factory = (ref, props) => ; diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx new file mode 100644 index 00000000000..71142352edb --- /dev/null +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx @@ -0,0 +1,21 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import React, { useSyncExternalStore } from "react"; +import { type JSX } from "react"; + +import { type TextualEventViewModel } from "../../../viewmodels/event-tiles/TextualEventViewModel"; + +interface Props { + vm: TextualEventViewModel; +} + +export function TextualEvent({ vm }: Props): JSX.Element { + const text = useSyncExternalStore(vm.subscribe, vm.getSnapshot); + + return
{text}
; +} diff --git a/src/shared-components/event-tiles/TextualEvent/index.ts b/src/shared-components/event-tiles/TextualEvent/index.ts new file mode 100644 index 00000000000..96f257fbfa1 --- /dev/null +++ b/src/shared-components/event-tiles/TextualEvent/index.ts @@ -0,0 +1,8 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +export { TextualEvent } from "./TextualEvent"; diff --git a/src/viewmodels/event-tiles/TextualEventViewModel.ts b/src/viewmodels/event-tiles/TextualEventViewModel.ts new file mode 100644 index 00000000000..6cb08c767ca --- /dev/null +++ b/src/viewmodels/event-tiles/TextualEventViewModel.ts @@ -0,0 +1,57 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import { type ReactNode } from "react"; +import { MatrixEventEvent } from "matrix-js-sdk/src/matrix"; + +import { type EventTileTypeProps } from "../../events/EventTileFactory"; +import { MatrixClientPeg } from "../../MatrixClientPeg"; +import { textForEvent } from "../../TextForEvent"; + +export class TextualEventViewModel { + private listeners = new Set(); + + public constructor(private eventTileProps: EventTileTypeProps) {} + + public subscribe = (listener: CallableFunction) => { + this.listeners.add(listener); + this.updateSubscription(); + + return () => { + this.listeners.delete(listener); + this.updateSubscription(); + }; + }; + + private emit(): void { + for (const listener of this.listeners) { + listener(); + } + } + + private updateSubscription(): void { + if (this.listeners.size > 0) { + this.eventTileProps.mxEvent.on(MatrixEventEvent.SentinelUpdated, this.onEventSentinelUpdated); + } else { + this.eventTileProps.mxEvent.off(MatrixEventEvent.SentinelUpdated, this.onEventSentinelUpdated); + } + } + + private onEventSentinelUpdated = (): void => { + this.emit(); + }; + + public getSnapshot = (): string | ReactNode => { + const text = textForEvent( + this.eventTileProps.mxEvent, + MatrixClientPeg.safeGet(), + true, + /*this.context?.showHiddenEvents*/ true, + ); + return text; + }; +} From ddbe0989ed305ce57c9f4b4dc7b0652c365ea7b8 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jun 2025 11:42:33 +0100 Subject: [PATCH 02/30] Remove old TextualEvent --- .../views/messages/TextualEvent.tsx | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 src/components/views/messages/TextualEvent.tsx diff --git a/src/components/views/messages/TextualEvent.tsx b/src/components/views/messages/TextualEvent.tsx deleted file mode 100644 index 445913bfc6e..00000000000 --- a/src/components/views/messages/TextualEvent.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2024 New Vector Ltd. -Copyright 2015-2021 The Matrix.org Foundation C.I.C. - -SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial -Please see LICENSE files in the repository root for full details. -*/ - -import React from "react"; -import { type MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/matrix"; - -import RoomContext from "../../../contexts/RoomContext"; -import * as TextForEvent from "../../../TextForEvent"; -import { MatrixClientPeg } from "../../../MatrixClientPeg"; - -interface IProps { - mxEvent: MatrixEvent; -} - -export default class TextualEvent extends React.Component { - public static contextType = RoomContext; - declare public context: React.ContextType; - - public componentDidMount(): void { - this.props.mxEvent.on(MatrixEventEvent.SentinelUpdated, this.onEventSentinelUpdated); - } - public componentWillUnmount(): void { - this.props.mxEvent.off(MatrixEventEvent.SentinelUpdated, this.onEventSentinelUpdated); - } - - private onEventSentinelUpdated = (): void => { - // XXX: this is crap, but we don't have a better way to force a re-render - // Many TextForEvent handlers render parts of `event.sender` and `event.target` so ensure they are updated - this.forceUpdate(); - }; - - public render(): React.ReactNode { - const text = TextForEvent.textForEvent( - this.props.mxEvent, - MatrixClientPeg.safeGet(), - true, - this.context?.showHiddenEvents, - ); - if (!text) return null; - return
{text}
; - } -} From 017928455eb963cdf2c78fbcac02298c872ff204 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jun 2025 13:46:33 +0100 Subject: [PATCH 03/30] Pass showHiddenEvents Because we used it anyway, we just cheated by getting it from the context --- src/events/EventTileFactory.tsx | 4 ++++ src/viewmodels/event-tiles/TextualEventViewModel.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/events/EventTileFactory.tsx b/src/events/EventTileFactory.tsx index b771033a67e..edf7820190d 100644 --- a/src/events/EventTileFactory.tsx +++ b/src/events/EventTileFactory.tsx @@ -68,6 +68,7 @@ export interface EventTileTypeProps maxImageHeight?: number; // pixels overrideBodyTypes?: Record>; overrideEventTypes?: Record>; + showHiddenEvents: boolean; } type FactoryProps = Omit; @@ -313,6 +314,7 @@ export function renderTile( isSeeingThroughMessageHiddenForModeration, permalinkCreator, inhibitInteraction, + showHiddenEvents, }), ); default: @@ -336,6 +338,7 @@ export function renderTile( isSeeingThroughMessageHiddenForModeration, timestamp, inhibitInteraction, + showHiddenEvents, }), ); } @@ -398,6 +401,7 @@ export function renderReplyTile( getRelationsForEvent, isSeeingThroughMessageHiddenForModeration, permalinkCreator, + showHiddenEvents, }), ); } diff --git a/src/viewmodels/event-tiles/TextualEventViewModel.ts b/src/viewmodels/event-tiles/TextualEventViewModel.ts index 6cb08c767ca..5df6b4fc8c0 100644 --- a/src/viewmodels/event-tiles/TextualEventViewModel.ts +++ b/src/viewmodels/event-tiles/TextualEventViewModel.ts @@ -50,7 +50,7 @@ export class TextualEventViewModel { this.eventTileProps.mxEvent, MatrixClientPeg.safeGet(), true, - /*this.context?.showHiddenEvents*/ true, + this.eventTileProps.showHiddenEvents, ); return text; }; From 84d34e1332e9584f6ab978fb391adfaa477f342d Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jun 2025 16:08:39 +0100 Subject: [PATCH 04/30] Factor out common view model stuff --- src/components/views/rooms/EventTile.tsx | 3 ++ src/components/views/rooms/ReplyTile.tsx | 1 + .../event-tiles/TextualEvent/TextualEvent.tsx | 13 ++++--- src/viewmodels/ViewModel.ts | 11 ++++++ src/viewmodels/ViewModelSubscriptions.ts | 28 ++++++++++++++ .../event-tiles/TextualEventViewModel.ts | 37 ++++++++----------- 6 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 src/viewmodels/ViewModel.ts create mode 100644 src/viewmodels/ViewModelSubscriptions.ts diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index 2c10d0afd96..c1364a9ee20 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -1250,6 +1250,7 @@ export class UnwrappedEventTile extends React.Component highlights: this.props.highlights, highlightLink: this.props.highlightLink, permalinkCreator: this.props.permalinkCreator!, + showHiddenEvents: this.context.showHiddenEvents, }, this.context.showHiddenEvents, )} @@ -1396,6 +1397,7 @@ export class UnwrappedEventTile extends React.Component highlights: this.props.highlights, highlightLink: this.props.highlightLink, permalinkCreator: this.props.permalinkCreator, + showHiddenEvents: this.context.showHiddenEvents, }, this.context.showHiddenEvents, )} @@ -1447,6 +1449,7 @@ export class UnwrappedEventTile extends React.Component highlights: this.props.highlights, highlightLink: this.props.highlightLink, permalinkCreator: this.props.permalinkCreator, + showHiddenEvents: this.context.showHiddenEvents, }, this.context.showHiddenEvents, )} diff --git a/src/components/views/rooms/ReplyTile.tsx b/src/components/views/rooms/ReplyTile.tsx index 2db56e397e3..cf80b38272b 100644 --- a/src/components/views/rooms/ReplyTile.tsx +++ b/src/components/views/rooms/ReplyTile.tsx @@ -163,6 +163,7 @@ export default class ReplyTile extends React.PureComponent { highlights: this.props.highlights, highlightLink: this.props.highlightLink, permalinkCreator: this.props.permalinkCreator, + showHiddenEvents: false, }, false /* showHiddenEvents shouldn't be relevant */, )} diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx index 71142352edb..55360816f92 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx @@ -5,17 +5,18 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import React, { useSyncExternalStore } from "react"; -import { type JSX } from "react"; +import React, { type ReactNode, useSyncExternalStore, type JSX } from "react"; -import { type TextualEventViewModel } from "../../../viewmodels/event-tiles/TextualEventViewModel"; +import { type ViewModel } from "../../../viewmodels/ViewModel"; + +export type TextualEventViewSnapshot = string | ReactNode; interface Props { - vm: TextualEventViewModel; + vm: ViewModel; } export function TextualEvent({ vm }: Props): JSX.Element { - const text = useSyncExternalStore(vm.subscribe, vm.getSnapshot); + const contents = useSyncExternalStore(vm.subscribe, vm.getSnapshot); - return
{text}
; + return
{contents}
; } diff --git a/src/viewmodels/ViewModel.ts b/src/viewmodels/ViewModel.ts new file mode 100644 index 00000000000..4a7c820fdb8 --- /dev/null +++ b/src/viewmodels/ViewModel.ts @@ -0,0 +1,11 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +export interface ViewModel { + getSnapshot: () => T; + subscribe: (listener: () => void) => () => void; +} diff --git a/src/viewmodels/ViewModelSubscriptions.ts b/src/viewmodels/ViewModelSubscriptions.ts new file mode 100644 index 00000000000..ff263b2b5c3 --- /dev/null +++ b/src/viewmodels/ViewModelSubscriptions.ts @@ -0,0 +1,28 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +export class ViewModelSubscriptions { + private listeners = new Set<() => void>(); + + public constructor(private updateSubscription: () => void) {} + + public subscribe = (listener: () => void) => { + this.listeners.add(listener); + this.updateSubscription(); + + return () => { + this.listeners.delete(listener); + this.updateSubscription(); + }; + }; + + public emit(): void { + for (const listener of this.listeners) { + listener(); + } + } +} diff --git a/src/viewmodels/event-tiles/TextualEventViewModel.ts b/src/viewmodels/event-tiles/TextualEventViewModel.ts index 5df6b4fc8c0..63cf132c2d9 100644 --- a/src/viewmodels/event-tiles/TextualEventViewModel.ts +++ b/src/viewmodels/event-tiles/TextualEventViewModel.ts @@ -5,47 +5,36 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { type ReactNode } from "react"; import { MatrixEventEvent } from "matrix-js-sdk/src/matrix"; import { type EventTileTypeProps } from "../../events/EventTileFactory"; import { MatrixClientPeg } from "../../MatrixClientPeg"; import { textForEvent } from "../../TextForEvent"; +import { ViewModelSubscriptions } from "../ViewModelSubscriptions"; +import { type TextualEventViewSnapshot } from "../../shared-components/event-tiles/TextualEvent/TextualEvent"; export class TextualEventViewModel { - private listeners = new Set(); - - public constructor(private eventTileProps: EventTileTypeProps) {} - - public subscribe = (listener: CallableFunction) => { - this.listeners.add(listener); - this.updateSubscription(); + private subs: ViewModelSubscriptions; - return () => { - this.listeners.delete(listener); - this.updateSubscription(); - }; - }; + private listeners = new Set(); - private emit(): void { - for (const listener of this.listeners) { - listener(); - } + public constructor(private eventTileProps: EventTileTypeProps) { + this.subs = new ViewModelSubscriptions(this.updateSubscription); } - private updateSubscription(): void { + private updateSubscription = (): void => { if (this.listeners.size > 0) { this.eventTileProps.mxEvent.on(MatrixEventEvent.SentinelUpdated, this.onEventSentinelUpdated); } else { this.eventTileProps.mxEvent.off(MatrixEventEvent.SentinelUpdated, this.onEventSentinelUpdated); } - } + }; - private onEventSentinelUpdated = (): void => { - this.emit(); + public subscribe = (listener: () => void): (() => void) => { + return this.subs.subscribe(listener); }; - public getSnapshot = (): string | ReactNode => { + public getSnapshot = (): TextualEventViewSnapshot => { const text = textForEvent( this.eventTileProps.mxEvent, MatrixClientPeg.safeGet(), @@ -54,4 +43,8 @@ export class TextualEventViewModel { ); return text; }; + + private onEventSentinelUpdated = (): void => { + this.subs.emit(); + }; } From b96da8de837b42034580bf1e2b0ac655c357a2be Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jun 2025 16:12:34 +0100 Subject: [PATCH 05/30] Move ViewModel interface into the shared components --- src/{viewmodels => shared-components}/ViewModel.ts | 0 src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{viewmodels => shared-components}/ViewModel.ts (100%) diff --git a/src/viewmodels/ViewModel.ts b/src/shared-components/ViewModel.ts similarity index 100% rename from src/viewmodels/ViewModel.ts rename to src/shared-components/ViewModel.ts diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx index 55360816f92..7caf5caf88e 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. import React, { type ReactNode, useSyncExternalStore, type JSX } from "react"; -import { type ViewModel } from "../../../viewmodels/ViewModel"; +import { type ViewModel } from "../../ViewModel"; export type TextualEventViewSnapshot = string | ReactNode; From 455ca447eaf2026e545adac73b4e398c2874bcca Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jun 2025 16:15:46 +0100 Subject: [PATCH 06/30] Add tiny wrapper hook --- .../event-tiles/TextualEvent/TextualEvent.tsx | 5 +++-- src/shared-components/useViewModel.ts | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 src/shared-components/useViewModel.ts diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx index 7caf5caf88e..cc351a3b3c5 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx @@ -5,9 +5,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import React, { type ReactNode, useSyncExternalStore, type JSX } from "react"; +import React, { type ReactNode, type JSX } from "react"; import { type ViewModel } from "../../ViewModel"; +import { useViewModel } from "../../useViewModel"; export type TextualEventViewSnapshot = string | ReactNode; @@ -16,7 +17,7 @@ interface Props { } export function TextualEvent({ vm }: Props): JSX.Element { - const contents = useSyncExternalStore(vm.subscribe, vm.getSnapshot); + const contents = useViewModel(vm); return
{contents}
; } diff --git a/src/shared-components/useViewModel.ts b/src/shared-components/useViewModel.ts new file mode 100644 index 00000000000..c714513ae59 --- /dev/null +++ b/src/shared-components/useViewModel.ts @@ -0,0 +1,14 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import { useSyncExternalStore } from "react"; + +import { type ViewModel } from "./ViewModel"; + +export function useViewModel(vm: ViewModel): T { + return useSyncExternalStore(vm.subscribe, vm.getSnapshot); +} From 73d78f4be6eaf07f542fff7dccab3389e575bf74 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 26 Jun 2025 16:22:50 +0100 Subject: [PATCH 07/30] Move showHiddenEvents into props fully --- src/components/views/rooms/EventTile.tsx | 92 +++++++++++------------- src/events/EventTileFactory.tsx | 4 +- 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/src/components/views/rooms/EventTile.tsx b/src/components/views/rooms/EventTile.tsx index c1364a9ee20..afef8b92e06 100644 --- a/src/components/views/rooms/EventTile.tsx +++ b/src/components/views/rooms/EventTile.tsx @@ -1237,23 +1237,19 @@ export class UnwrappedEventTile extends React.Component
{this.renderContextMenu()} {replyChain} - {renderTile( - TimelineRenderingType.Thread, - { - ...this.props, - - // overrides - ref: this.tile, - isSeeingThroughMessageHiddenForModeration, - - // appease TS - highlights: this.props.highlights, - highlightLink: this.props.highlightLink, - permalinkCreator: this.props.permalinkCreator!, - showHiddenEvents: this.context.showHiddenEvents, - }, - this.context.showHiddenEvents, - )} + {renderTile(TimelineRenderingType.Thread, { + ...this.props, + + // overrides + ref: this.tile, + isSeeingThroughMessageHiddenForModeration, + + // appease TS + highlights: this.props.highlights, + highlightLink: this.props.highlightLink, + permalinkCreator: this.props.permalinkCreator!, + showHiddenEvents: this.context.showHiddenEvents, + })} {actionBar} {timestamp} @@ -1384,23 +1380,19 @@ export class UnwrappedEventTile extends React.Component ,
{this.renderContextMenu()} - {renderTile( - TimelineRenderingType.File, - { - ...this.props, - - // overrides - ref: this.tile, - isSeeingThroughMessageHiddenForModeration, - - // appease TS - highlights: this.props.highlights, - highlightLink: this.props.highlightLink, - permalinkCreator: this.props.permalinkCreator, - showHiddenEvents: this.context.showHiddenEvents, - }, - this.context.showHiddenEvents, - )} + {renderTile(TimelineRenderingType.File, { + ...this.props, + + // overrides + ref: this.tile, + isSeeingThroughMessageHiddenForModeration, + + // appease TS + highlights: this.props.highlights, + highlightLink: this.props.highlightLink, + permalinkCreator: this.props.permalinkCreator, + showHiddenEvents: this.context.showHiddenEvents, + })}
, ], ); @@ -1435,24 +1427,20 @@ export class UnwrappedEventTile extends React.Component {groupTimestamp} {groupPadlock} {replyChain} - {renderTile( - this.context.timelineRenderingType, - { - ...this.props, - - // overrides - ref: this.tile, - isSeeingThroughMessageHiddenForModeration, - timestamp: bubbleTimestamp, - - // appease TS - highlights: this.props.highlights, - highlightLink: this.props.highlightLink, - permalinkCreator: this.props.permalinkCreator, - showHiddenEvents: this.context.showHiddenEvents, - }, - this.context.showHiddenEvents, - )} + {renderTile(this.context.timelineRenderingType, { + ...this.props, + + // overrides + ref: this.tile, + isSeeingThroughMessageHiddenForModeration, + timestamp: bubbleTimestamp, + + // appease TS + highlights: this.props.highlights, + highlightLink: this.props.highlightLink, + permalinkCreator: this.props.permalinkCreator, + showHiddenEvents: this.context.showHiddenEvents, + })} {actionBar} {this.props.layout === Layout.IRC && ( <> diff --git a/src/events/EventTileFactory.tsx b/src/events/EventTileFactory.tsx index edf7820190d..9d0daadb80a 100644 --- a/src/events/EventTileFactory.tsx +++ b/src/events/EventTileFactory.tsx @@ -257,12 +257,11 @@ export function pickFactory( export function renderTile( renderType: TimelineRenderingType, props: EventTileTypeProps, - showHiddenEvents: boolean, cli?: MatrixClient, ): Optional { cli = cli ?? MatrixClientPeg.safeGet(); // because param defaults don't do the correct thing - const factory = pickFactory(props.mxEvent, cli, showHiddenEvents); + const factory = pickFactory(props.mxEvent, cli, props.showHiddenEvents); if (!factory) { // If we don't have a factory for this event, attempt // to find a custom component that can render it. @@ -291,6 +290,7 @@ export function renderTile( isSeeingThroughMessageHiddenForModeration, timestamp, inhibitInteraction, + showHiddenEvents, } = props; switch (renderType) { From 2125415654aec1e4ba3ddd8a8d89bf52c4191424 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Jun 2025 15:02:47 +0100 Subject: [PATCH 08/30] Fill in stories / test --- .../TextualEvent/TextualEvent.stories.tsx | 22 +++++++++++++++++++ .../TextualEvent/TextualEvent.test.tsx | 21 ++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx index e69de29bb2d..c16f29c35e1 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx @@ -0,0 +1,22 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import React from "react"; +import { type Meta, type StoryFn } from "@storybook/react"; + +import { TextualEvent as TextualEventComponent } from "./TextualEvent"; + +export default { + title: "Icon/BigIcon", + component: TextualEventComponent, + tags: ["autodocs"], + args: {}, +} as Meta; + +const Template: StoryFn = (args) => ; + +export const Default = Template.bind({}); diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx index e69de29bb2d..04ea727f978 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx @@ -0,0 +1,21 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +import { composeStories } from "@storybook/react"; +import { render } from "jest-matrix-react"; +import React from "react"; + +import * as stories from "./TextualEvent.stories.tsx"; + +const { Default } = composeStories(stories); + +describe("TextualEvent", () => { + it("renders a textual event", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); +}); From a597221d05a375861ee5127acd8d1686323b8688 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Fri, 20 Jun 2025 14:20:26 +0200 Subject: [PATCH 09/30] chore: setup storybook cherry pick edc5e8705674b8708d986910b02b5d2545777fb3 from florianduros/storybook --- .eslintrc.js | 7 +- .gitignore | 3 + .storybook/ElementTheme.ts | 21 + .storybook/main.ts | 46 ++ .storybook/manager.js | 6 + .storybook/preview.css | 3 + .storybook/preview.tsx | 56 +++ declaration.d.ts | 8 + package.json | 11 +- res/css/shared.pcss | 9 + tsconfig.json | 3 +- yarn.lock | 980 +++++++++++++++++++++++++++++++++++-- 12 files changed, 1100 insertions(+), 53 deletions(-) create mode 100644 .storybook/ElementTheme.ts create mode 100644 .storybook/main.ts create mode 100644 .storybook/manager.js create mode 100644 .storybook/preview.css create mode 100644 .storybook/preview.tsx create mode 100644 declaration.d.ts create mode 100644 res/css/shared.pcss diff --git a/.eslintrc.js b/.eslintrc.js index 26865d55ec2..9c88bdba9c9 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,6 +1,11 @@ module.exports = { plugins: ["matrix-org", "eslint-plugin-react-compiler"], - extends: ["plugin:matrix-org/babel", "plugin:matrix-org/react", "plugin:matrix-org/a11y"], + extends: [ + "plugin:matrix-org/babel", + "plugin:matrix-org/react", + "plugin:matrix-org/a11y", + "plugin:storybook/recommended", + ], parserOptions: { project: ["./tsconfig.json"], }, diff --git a/.gitignore b/.gitignore index 429b317a4f0..efc96c54256 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ electron/pub /index.html # version file and tarball created by `npm pack` / `yarn pack` /git-revision.txt + +*storybook.log +storybook-static diff --git a/.storybook/ElementTheme.ts b/.storybook/ElementTheme.ts new file mode 100644 index 00000000000..00b1a601886 --- /dev/null +++ b/.storybook/ElementTheme.ts @@ -0,0 +1,21 @@ +import { create } from "storybook/theming"; + +export default create({ + base: "light", + + // Colors + textColor: "#1b1d22", + colorSecondary: "#111111", + + // UI + appBg: "#ffffff", + appContentBg: "#ffffff", + + // Toolbar + barBg: "#ffffff", + + brandTitle: "Element Web", + brandUrl: "https://github.com/element-hq/element-web", + brandImage: "https://element.io/images/logo-ele-secondary.svg", + brandTarget: "_self", +}); diff --git a/.storybook/main.ts b/.storybook/main.ts new file mode 100644 index 00000000000..27703dbd687 --- /dev/null +++ b/.storybook/main.ts @@ -0,0 +1,46 @@ +import type { StorybookConfig } from "@storybook/react-webpack5"; + +const config: StorybookConfig = { + stories: ["../src/shared/**/*.mdx", "../src/shared/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + addons: [ + "@storybook/addon-webpack5-compiler-swc", + "@storybook/addon-docs", + "@storybook/addon-designs", + { + name: "@storybook/addon-styling-webpack", + options: { + rules: [ + { + test: /\.module.css$/, + use: [ + "style-loader", + { + loader: "css-loader", + options: { + importLoaders: 1, + modules: { + namedExport: false, + }, + }, + }, + ], + }, + // Replaces existing CSS rules with given rule + { + test: /\.p?css$/, + exclude: /\.module.css$/, + use: ["style-loader", "css-loader"], + }, + ], + }, + }, + ], + framework: "@storybook/react-webpack5", + core: { + disableTelemetry: true, + }, + typescript: { + reactDocgen: "react-docgen-typescript", + }, +}; +export default config; diff --git a/.storybook/manager.js b/.storybook/manager.js new file mode 100644 index 00000000000..97fe237a184 --- /dev/null +++ b/.storybook/manager.js @@ -0,0 +1,6 @@ +import { addons } from "storybook/manager-api"; +import ElementTheme from "./ElementTheme"; + +addons.setConfig({ + theme: ElementTheme, +}); diff --git a/.storybook/preview.css b/.storybook/preview.css new file mode 100644 index 00000000000..c0d2b88a84c --- /dev/null +++ b/.storybook/preview.css @@ -0,0 +1,3 @@ +.docs-story { + background: var(--cpd-color-bg-canvas-default); +} diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx new file mode 100644 index 00000000000..59806dcb23c --- /dev/null +++ b/.storybook/preview.tsx @@ -0,0 +1,56 @@ +import type { ArgTypes, Preview, Decorator } from "@storybook/react-webpack5"; + +import "../res/css/shared.pcss"; +import "./preview.css"; +import React, { useLayoutEffect } from "react"; + +export const globalTypes = { + theme: { + name: "Theme", + defaultValue: "system", + description: "Global theme for components", + toolbar: { + icon: "circlehollow", + title: "Theme", + items: [ + { title: "System", value: "system", icon: "browser" }, + { title: "Light", value: "light", icon: "sun" }, + { title: "Light (high contrast)", value: "light-hc", icon: "sun" }, + { title: "Dark", value: "dark", icon: "moon" }, + { title: "Dark (high contrast)", value: "dark-hc", icon: "moon" }, + ], + }, + }, +} satisfies ArgTypes; + +const allThemesClasses = globalTypes.theme.toolbar.items.map(({ value }) => `cpd-theme-${value}`); + +const ThemeSwitcher: React.FC<{ + theme: string; +}> = ({ theme }) => { + useLayoutEffect(() => { + document.documentElement.classList.remove(...allThemesClasses); + if (theme !== "system") { + document.documentElement.classList.add(`cpd-theme-${theme}`); + } + return () => document.documentElement.classList.remove(...allThemesClasses); + }, [theme]); + + return null; +}; + +const withThemeProvider: Decorator = (Story, context) => { + return ( + <> + + + + ); +}; + +const preview: Preview = { + tags: ["autodocs"], + decorators: [withThemeProvider], +}; + +export default preview; diff --git a/declaration.d.ts b/declaration.d.ts new file mode 100644 index 00000000000..928c567c31e --- /dev/null +++ b/declaration.d.ts @@ -0,0 +1,8 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +declare module "*.module.css"; diff --git a/package.json b/package.json index 80a0e0f8227..a8f3538febc 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,9 @@ "coverage": "yarn test --coverage", "analyse:webpack-bundles": "webpack-bundle-analyzer webpack-stats.json webapp", "update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js", - "postinstall": "patch-package" + "postinstall": "patch-package", + "storybook": "storybook dev -p 6007", + "build-storybook": "storybook build" }, "resolutions": { "**/pretty-format/react-is": "19.1.0", @@ -187,6 +189,11 @@ "@principalstudio/html-webpack-inject-preload": "^1.2.7", "@rrweb/types": "^2.0.0-alpha.18", "@sentry/webpack-plugin": "^3.0.0", + "@storybook/addon-designs": "^10.0.1", + "@storybook/addon-docs": "^9.0.12", + "@storybook/addon-styling-webpack": "^2.0.0", + "@storybook/addon-webpack5-compiler-swc": "^3.0.0", + "@storybook/react-webpack5": "^9.0.12", "@stylistic/eslint-plugin": "^4.0.0", "@svgr/webpack": "^8.0.0", "@testing-library/dom": "^10.4.0", @@ -246,6 +253,7 @@ "eslint-plugin-react": "^7.28.0", "eslint-plugin-react-compiler": "^19.0.0-beta-df7b47d-20241124", "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-storybook": "^9.0.12", "eslint-plugin-unicorn": "^56.0.0", "express": "^5.0.0", "fake-indexeddb": "^6.0.0", @@ -285,6 +293,7 @@ "rimraf": "^6.0.0", "semver": "^7.5.2", "source-map-loader": "^5.0.0", + "storybook": "^9.0.12", "stylelint": "^16.13.0", "stylelint-config-standard": "^38.0.0", "stylelint-scss": "^6.0.0", diff --git a/res/css/shared.pcss b/res/css/shared.pcss new file mode 100644 index 00000000000..42f83936668 --- /dev/null +++ b/res/css/shared.pcss @@ -0,0 +1,9 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +@import url("@vector-im/compound-design-tokens/assets/web/css/compound-design-tokens.css") layer(compound); +@import url("@vector-im/compound-web/dist/style.css"); diff --git a/tsconfig.json b/tsconfig.json index 10d7c216b65..178cc1be40c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,7 +26,8 @@ "./src/**/*.tsx", "./test/**/*.ts", "./test/**/*.tsx", - "./scripts/*.ts" + "./scripts/*.ts", + "./declaration.d.ts", ], "ts-node": { "files": true, diff --git a/yarn.lock b/yarn.lock index 73816acb98a..c720d2120e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,7 +34,7 @@ dependencies: axe-core "~4.10.3" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.27.1": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== @@ -65,7 +65,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.5.tgz#7d0658ec1a8420fc866d1df1b03bea0e79934c82" integrity sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg== -"@babel/core@^7.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.18.5", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.24.4": +"@babel/core@^7.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.18.5", "@babel/core@^7.18.9", "@babel/core@^7.21.3", "@babel/core@^7.23.9", "@babel/core@^7.24.4": version "7.27.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.27.4.tgz#cc1fc55d0ce140a1828d1dd2a2eba285adbfb3ce" integrity sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g== @@ -1224,6 +1224,19 @@ debug "^4.3.1" globals "^11.1.0" +"@babel/traverse@^7.18.9", "@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3", "@babel/traverse@^7.27.4": + version "7.27.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.4.tgz#b0045ac7023c8472c3d35effd7cc9ebd638da6ea" + integrity sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.27.3" + "@babel/parser" "^7.27.4" + "@babel/template" "^7.27.2" + "@babel/types" "^7.27.3" + debug "^4.3.1" + globals "^11.1.0" + "@babel/traverse@^7.25.9", "@babel/traverse@^7.26.5": version "7.27.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.0.tgz#11d7e644779e166c0442f9a07274d02cd91d4a70" @@ -1250,19 +1263,6 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/traverse@^7.27.1", "@babel/traverse@^7.27.3", "@babel/traverse@^7.27.4": - version "7.27.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.4.tgz#b0045ac7023c8472c3d35effd7cc9ebd638da6ea" - integrity sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA== - dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.27.3" - "@babel/parser" "^7.27.4" - "@babel/template" "^7.27.2" - "@babel/types" "^7.27.3" - debug "^4.3.1" - globals "^11.1.0" - "@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.25.8", "@babel/types@^7.3.3": version "7.25.8" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" @@ -1272,6 +1272,14 @@ "@babel/helper-validator-identifier" "^7.25.7" to-fast-properties "^2.0.0" +"@babel/types@^7.18.9", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.27.6": + version "7.27.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.6.tgz#a434ca7add514d4e646c80f7375c0aa2befc5535" + integrity sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/types@^7.25.7": version "7.26.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.0.tgz#deabd08d6b753bc8e0f198f8709fb575e31774ff" @@ -1296,14 +1304,6 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" -"@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.27.6": - version "7.27.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.6.tgz#a434ca7add514d4e646c80f7375c0aa2befc5535" - integrity sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q== - dependencies: - "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@balena/dockerignore@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" @@ -1713,6 +1713,131 @@ dependencies: tslib "^2.4.0" +"@esbuild/aix-ppc64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz#4e0f91776c2b340e75558f60552195f6fad09f18" + integrity sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA== + +"@esbuild/android-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz#bc766407f1718923f6b8079c8c61bf86ac3a6a4f" + integrity sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg== + +"@esbuild/android-arm@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.5.tgz#4290d6d3407bae3883ad2cded1081a234473ce26" + integrity sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA== + +"@esbuild/android-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.5.tgz#40c11d9cbca4f2406548c8a9895d321bc3b35eff" + integrity sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw== + +"@esbuild/darwin-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz#49d8bf8b1df95f759ac81eb1d0736018006d7e34" + integrity sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ== + +"@esbuild/darwin-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz#e27a5d92a14886ef1d492fd50fc61a2d4d87e418" + integrity sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ== + +"@esbuild/freebsd-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz#97cede59d638840ca104e605cdb9f1b118ba0b1c" + integrity sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw== + +"@esbuild/freebsd-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz#71c77812042a1a8190c3d581e140d15b876b9c6f" + integrity sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw== + +"@esbuild/linux-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz#f7b7c8f97eff8ffd2e47f6c67eb5c9765f2181b8" + integrity sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg== + +"@esbuild/linux-arm@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz#2a0be71b6cd8201fa559aea45598dffabc05d911" + integrity sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw== + +"@esbuild/linux-ia32@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz#763414463cd9ea6fa1f96555d2762f9f84c61783" + integrity sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA== + +"@esbuild/linux-loong64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz#428cf2213ff786a502a52c96cf29d1fcf1eb8506" + integrity sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg== + +"@esbuild/linux-mips64el@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz#5cbcc7fd841b4cd53358afd33527cd394e325d96" + integrity sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg== + +"@esbuild/linux-ppc64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz#0d954ab39ce4f5e50f00c4f8c4fd38f976c13ad9" + integrity sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ== + +"@esbuild/linux-riscv64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz#0e7dd30730505abd8088321e8497e94b547bfb1e" + integrity sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA== + +"@esbuild/linux-s390x@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz#5669af81327a398a336d7e40e320b5bbd6e6e72d" + integrity sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ== + +"@esbuild/linux-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz#b2357dd153aa49038967ddc1ffd90c68a9d2a0d4" + integrity sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw== + +"@esbuild/netbsd-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz#53b4dfb8fe1cee93777c9e366893bd3daa6ba63d" + integrity sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw== + +"@esbuild/netbsd-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz#a0206f6314ce7dc8713b7732703d0f58de1d1e79" + integrity sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ== + +"@esbuild/openbsd-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz#2a796c87c44e8de78001d808c77d948a21ec22fd" + integrity sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw== + +"@esbuild/openbsd-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz#28d0cd8909b7fa3953af998f2b2ed34f576728f0" + integrity sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg== + +"@esbuild/sunos-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz#a28164f5b997e8247d407e36c90d3fd5ddbe0dc5" + integrity sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA== + +"@esbuild/win32-arm64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz#6eadbead38e8bd12f633a5190e45eff80e24007e" + integrity sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw== + +"@esbuild/win32-ia32@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz#bab6288005482f9ed2adb9ded7e88eba9a62cc0d" + integrity sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ== + +"@esbuild/win32-x64@0.25.5": + version "0.25.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz#7fc114af5f6563f19f73324b5d5ff36ece0803d1" + integrity sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -1764,6 +1889,21 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== +"@figspec/components@^1.0.1": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@figspec/components/-/components-1.0.3.tgz#6456970a7298f9969d4d329574435050fcac00d9" + integrity sha512-fBwHzJ4ouuOUJEi+yBZIrOy+0/fAjB3AeTcIHTT1PRxLz8P63xwC7R0EsIJXhScIcc+PljGmqbbVJCjLsnaGYA== + dependencies: + lit "^2.1.3" + +"@figspec/react@^1.0.0": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@figspec/react/-/react-1.0.4.tgz#c45e740a2873bf6cd8f4576390d58dab06478fc5" + integrity sha512-jaPvkIef4d6NjsRiw91OZabrfdPH9FtoPGYcY5mpXjYEcdUqIq1aHtLq3SkMVyVysEapTEJ6yS8amy93MyXBEQ== + dependencies: + "@figspec/components" "^1.0.1" + "@lit-labs/react" "^1.0.2" + "@floating-ui/core@^1.6.0": version "1.6.8" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.8.tgz#aa43561be075815879305965020f492cdb43da12" @@ -2139,7 +2279,7 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== @@ -2197,6 +2337,23 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== +"@lit-labs/react@^1.0.2": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@lit-labs/react/-/react-1.2.1.tgz#5b421502cdf68a3639dec431318eeed2285f1c0e" + integrity sha512-DiZdJYFU0tBbdQkfwwRSwYyI/mcWkg3sWesKRsHUd4G+NekTmmeq9fzsurvcKTNVa0comNljwtg4Hvi1ds3V+A== + +"@lit-labs/ssr-dom-shim@^1.0.0", "@lit-labs/ssr-dom-shim@^1.1.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz#a28799c463177d1a0b0e5cefdc173da5ac859eb4" + integrity sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ== + +"@lit/reactive-element@^1.3.0", "@lit/reactive-element@^1.6.0": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.6.3.tgz#25b4eece2592132845d303e091bad9b04cdcfe03" + integrity sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.0.0" + "@mapbox/geojson-rewind@^0.5.2": version "0.5.2" resolved "https://registry.yarnpkg.com/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz#591a5d71a9cd1da1a0bf3420b3bea31b0fc7946a" @@ -2280,6 +2437,13 @@ resolved "https://registry.yarnpkg.com/@matrix-org/spec/-/spec-1.14.0.tgz#cedc4f9cc86c9e623ccd4f643629bac97bc0fed2" integrity sha512-UI4kY6WXniRV++ZeMesmCvZMH8lANLc12rnca1/M+nkPgJgU9GQd5X9ezFoOLabG6tGdEUPPKr5/S2EP1FdGLA== +"@mdx-js/react@^3.0.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.1.0.tgz#c4522e335b3897b9a845db1dbdd2f966ae8fb0ed" + integrity sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ== + dependencies: + "@types/mdx" "^2.0.0" + "@napi-rs/wasm-runtime@^0.2.11": version "0.2.11" resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz#192c1610e1625048089ab4e35bc0649ce478500e" @@ -2924,6 +3088,135 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@storybook/addon-designs@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@storybook/addon-designs/-/addon-designs-10.0.1.tgz#20c12e848fe05181784a1b12d4f7e8b03ef12e35" + integrity sha512-R+C9DRN7nYmPpPSMXzDNmdDY9XEclH90CYvSbCntNvizazlAUnZnkOaO0Bko/UK7guC+eEQ0bFYaxxndYu+dsA== + dependencies: + "@figspec/react" "^1.0.0" + +"@storybook/addon-docs@^9.0.12": + version "9.0.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-9.0.12.tgz#7c5dc7bd749c80a5d69a969242c4d3914669c0da" + integrity sha512-bAuFy4BWGEBIC0EAS4N+V8mHj7NZiSdDnJUSr4Al3znEVzNHLpQAMRznkga2Ok8x+gwcyBG7W47dLbDXVqLZDg== + dependencies: + "@mdx-js/react" "^3.0.0" + "@storybook/csf-plugin" "9.0.12" + "@storybook/icons" "^1.2.12" + "@storybook/react-dom-shim" "9.0.12" + react "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + react-dom "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-styling-webpack@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@storybook/addon-styling-webpack/-/addon-styling-webpack-2.0.0.tgz#3e854c82a835a6df439a69e307f337b39b4a4cab" + integrity sha512-N8jWhWnk3/nbL4P9zl0OEV/47P0Cxn/kPzSHjdAClyDYnqj9jI6upeLsraZgIV9Ro3QSeqeIloeXb1zMasWpOw== + +"@storybook/addon-webpack5-compiler-swc@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@storybook/addon-webpack5-compiler-swc/-/addon-webpack5-compiler-swc-3.0.0.tgz#78388c5d8a8375fe99f3b964057bc0402274e7d5" + integrity sha512-qkQwQEvHlxwPCHz/xakGfXJusEa1gKMw7enELh6QGopblfN3rMiV084boqiIqBReqWTasSwHOqvuElAu0NQ+8w== + dependencies: + "@swc/core" "^1.10.8" + swc-loader "^0.2.6" + +"@storybook/builder-webpack5@9.0.12": + version "9.0.12" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-9.0.12.tgz#c050ef1f4f282aa2afb121f4720e066c504c7828" + integrity sha512-zfmGYZjDppYPZZgSwW9ZRfIrCvshZcLombKmVEodlt/RMs5N5zaTCNf5p7+Z1BBcRpH5HXHWjwmrlobW6LzsLg== + dependencies: + "@storybook/core-webpack" "9.0.12" + case-sensitive-paths-webpack-plugin "^2.4.0" + cjs-module-lexer "^1.2.3" + css-loader "^6.7.1" + es-module-lexer "^1.5.0" + fork-ts-checker-webpack-plugin "^8.0.0" + html-webpack-plugin "^5.5.0" + magic-string "^0.30.5" + style-loader "^3.3.1" + terser-webpack-plugin "^5.3.1" + ts-dedent "^2.0.0" + webpack "5" + webpack-dev-middleware "^6.1.2" + webpack-hot-middleware "^2.25.1" + webpack-virtual-modules "^0.6.0" + +"@storybook/core-webpack@9.0.12": + version "9.0.12" + resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-9.0.12.tgz#d2a09f9b7eb5b6e87226d05661c0cc6215cbf72f" + integrity sha512-soFgpQh8pfba94YjkFBMNO4460/NEhdWe2WUPJs5drz2tOyGSElYma9KKjkbn+SQtr4qG0Xu7P56e8DJMXiMDg== + dependencies: + ts-dedent "^2.0.0" + +"@storybook/csf-plugin@9.0.12": + version "9.0.12" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-9.0.12.tgz#70d66934938e1fd79f2b570e09ce0ffe79492d2d" + integrity sha512-5EueJQJAu77Lh+EedG4Q/kEOZNlTY/g+fWsT7B5DTtLVy0ypnghsHY8X3KYT/0+NNgTtoO0if4F+ejVYaLnMzA== + dependencies: + unplugin "^1.3.1" + +"@storybook/global@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" + integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== + +"@storybook/icons@^1.2.12": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.4.0.tgz#7cf7ab3dfb41943930954c4ef493a73798d8b31d" + integrity sha512-Td73IeJxOyalzvjQL+JXx72jlIYHgs+REaHiREOqfpo3A2AYYG71AUbcv+lg7mEDIweKVCxsMQ0UKo634c8XeA== + +"@storybook/preset-react-webpack@9.0.12": + version "9.0.12" + resolved "https://registry.yarnpkg.com/@storybook/preset-react-webpack/-/preset-react-webpack-9.0.12.tgz#3a39887398f7c11b41fa55d44e6f31f82a2fa4e2" + integrity sha512-Tl3Qrll29dwltI4lP15zbeSXqikKa4Ucp6NKf4+W/4adzOqGRjj/bIzO3FsIPoGNs4wfy5DsOgUUPHxI4Jx97w== + dependencies: + "@storybook/core-webpack" "9.0.12" + "@storybook/react-docgen-typescript-plugin" "1.0.6--canary.9.0c3f3b7.0" + "@types/semver" "^7.3.4" + find-up "^7.0.0" + magic-string "^0.30.5" + react-docgen "^7.1.1" + resolve "^1.22.8" + semver "^7.3.7" + tsconfig-paths "^4.2.0" + webpack "5" + +"@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0": + version "1.0.6--canary.9.0c3f3b7.0" + resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz#7f10f3c641f32e4513a8b6ffb5036933e7059534" + integrity sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q== + dependencies: + debug "^4.1.1" + endent "^2.0.1" + find-cache-dir "^3.3.1" + flat-cache "^3.0.4" + micromatch "^4.0.2" + react-docgen-typescript "^2.2.2" + tslib "^2.0.0" + +"@storybook/react-dom-shim@9.0.12": + version "9.0.12" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-9.0.12.tgz#745d7ba464ef087ce8489c5ffb80ad5bc9bfe83d" + integrity sha512-OMBitzkJRga/UJF1ScSnaxgBSlAVePCK8wzPkGDn0MmsjZ4oDWuNZeKnVO1+tb6n2rZHws7RmKGxHzHAZTY+zQ== + +"@storybook/react-webpack5@^9.0.12": + version "9.0.12" + resolved "https://registry.yarnpkg.com/@storybook/react-webpack5/-/react-webpack5-9.0.12.tgz#15180a58eccd2287e2df1fd20f74f486e150150e" + integrity sha512-SHVwmmnodGcvLn0pclPu4P9b3qexUXTFPsGmtjQnGObZ3AqhjWiei8h4pYtX8m8zhu419QWevykJq6oWvYzHdA== + dependencies: + "@storybook/builder-webpack5" "9.0.12" + "@storybook/preset-react-webpack" "9.0.12" + "@storybook/react" "9.0.12" + +"@storybook/react@9.0.12": + version "9.0.12" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-9.0.12.tgz#7dd2c0312d29f83cc620f4285ec5af028f922d8f" + integrity sha512-rDrf5MDfsguNDTSOfGqhAjQDhp3jDMdzAoCqLjQ75M647C8nsv9i+fftO3k0rMxIJRrESpZWqVZ4tsjOX+J3DA== + dependencies: + "@storybook/global" "^5.0.0" + "@storybook/react-dom-shim" "9.0.12" + "@stylistic/eslint-plugin@^4.0.0": version "4.4.1" resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin/-/eslint-plugin-4.4.1.tgz#410ac332887fb3d61cad1df4e6b55ae35d87c632" @@ -3041,6 +3334,87 @@ "@svgr/plugin-jsx" "8.1.0" "@svgr/plugin-svgo" "8.1.0" +"@swc/core-darwin-arm64@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.12.1.tgz#a2aa56b644472f12e66357701ac8120cc331ed01" + integrity sha512-nUjWVcJ3YS2N40ZbKwYO2RJ4+o2tWYRzNOcIQp05FqW0+aoUCVMdAUUzQinPDynfgwVshDAXCKemY8X7nN5MaA== + +"@swc/core-darwin-x64@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.12.1.tgz#075049a2cfb386c3e533b535fd0ec4d1c851b3af" + integrity sha512-OGm4a4d3OeJn+tRt8H/eiHgTFrJbS6r8mi/Ob65tAEXZGHN900T2kR7c5ALr0V2hBOQ8BfhexwPoQlGQP/B95w== + +"@swc/core-linux-arm-gnueabihf@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.12.1.tgz#53ace44bc470eb96fc5115e2f83d240b11be98ae" + integrity sha512-76YeeQKyK0EtNkQiNBZ0nbVGooPf9IucY0WqVXVpaU4wuG7ZyLEE2ZAIgXafIuzODGQoLfetue7I8boMxh1/MA== + +"@swc/core-linux-arm64-gnu@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.12.1.tgz#d120abbb46d8d7f6b0ab831ee7868651ece87cd1" + integrity sha512-BxJDIJPq1+aCh9UsaSAN6wo3tuln8UhNXruOrzTI8/ElIig/3sAueDM6Eq7GvZSGGSA7ljhNATMJ0elD7lFatQ== + +"@swc/core-linux-arm64-musl@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.12.1.tgz#468732c327c657fde5a486daf910cbf60391a6a2" + integrity sha512-NhLdbffSXvY0/FwUSAl4hKBlpe5GHQGXK8DxTo3HHjLsD9sCPYieo3vG0NQoUYAy4ZUY1WeGjyxeq4qZddJzEQ== + +"@swc/core-linux-x64-gnu@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.12.1.tgz#fda705587c211400017f163a45c24706b42649ba" + integrity sha512-CrYnV8SZIgArQ9LKH0xEF95PKXzX9WkRSc5j55arOSBeDCeDUQk1Bg/iKdnDiuj5HC1hZpvzwMzSBJjv+Z70jA== + +"@swc/core-linux-x64-musl@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.12.1.tgz#c8d05ecdabbc23598d6bd880a2202eade55af9c9" + integrity sha512-BQMl3d0HaGB0/h2xcKlGtjk/cGRn2tnbsaChAKcjFdCepblKBCz1pgO/mL7w5iXq3s57wMDUn++71/a5RAkZOA== + +"@swc/core-win32-arm64-msvc@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.12.1.tgz#dea562db2529d82bedcb71be1030a01b88707fc6" + integrity sha512-b7NeGnpqTfmIGtUqXBl0KqoSmOnH64nRZoT5l4BAGdvwY7nxitWR94CqZuwyLPty/bLywmyDA9uO12Kvgb3+gg== + +"@swc/core-win32-ia32-msvc@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.12.1.tgz#8e2be4875df831b2c7d340bed0688094a914b03c" + integrity sha512-iU/29X2D7cHBp1to62cUg/5Xk8K+lyOJiKIGGW5rdzTW/c2zz3d/ehgpzVP/rqC4NVr88MXspqHU4il5gmDajw== + +"@swc/core-win32-x64-msvc@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.12.1.tgz#f0cf5136844cd42d93a6bff7c1be2b8cb1c71174" + integrity sha512-+Zh+JKDwiFqV5N9yAd2DhYVGPORGh9cfenu1ptr9yge+eHAf7vZJcC3rnj6QMR1QJh0Y5VC9+YBjRFjZVA7XDw== + +"@swc/core@^1.10.8": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.12.1.tgz#373759c60a3bf44a0dc02d411d31c31fbfd7c64b" + integrity sha512-aKXdDTqxTVFl/bKQZ3EQUjEMBEoF6JBv29moMZq0kbVO43na6u/u+3Vcbhbrh+A2N0X5OL4RaveuWfAjEgOmeA== + dependencies: + "@swc/counter" "^0.1.3" + "@swc/types" "^0.1.23" + optionalDependencies: + "@swc/core-darwin-arm64" "1.12.1" + "@swc/core-darwin-x64" "1.12.1" + "@swc/core-linux-arm-gnueabihf" "1.12.1" + "@swc/core-linux-arm64-gnu" "1.12.1" + "@swc/core-linux-arm64-musl" "1.12.1" + "@swc/core-linux-x64-gnu" "1.12.1" + "@swc/core-linux-x64-musl" "1.12.1" + "@swc/core-win32-arm64-msvc" "1.12.1" + "@swc/core-win32-ia32-msvc" "1.12.1" + "@swc/core-win32-x64-msvc" "1.12.1" + +"@swc/counter@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" + integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== + +"@swc/types@^0.1.23": + version "0.1.23" + resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.23.tgz#7eabf88b9cfd929253859c562ae95982ee04b4e8" + integrity sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw== + dependencies: + "@swc/counter" "^0.1.3" + "@testcontainers/postgresql@^11.0.0": version "11.0.3" resolved "https://registry.yarnpkg.com/@testcontainers/postgresql/-/postgresql-11.0.3.tgz#53387b2706ef519afdbe9064c025f51a62b4471d" @@ -3062,7 +3436,7 @@ lz-string "^1.5.0" pretty-format "^27.0.2" -"@testing-library/jest-dom@^6.4.8": +"@testing-library/jest-dom@^6.4.8", "@testing-library/jest-dom@^6.6.3": version "6.6.3" resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz#26ba906cf928c0f8172e182c6fe214eb4f9f2bd2" integrity sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA== @@ -3082,7 +3456,7 @@ dependencies: "@babel/runtime" "^7.12.5" -"@testing-library/user-event@^14.5.2": +"@testing-library/user-event@^14.5.2", "@testing-library/user-event@^14.6.1": version "14.6.1" resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.6.1.tgz#13e09a32d7a8b7060fe38304788ebf4197cd2149" integrity sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw== @@ -3129,7 +3503,7 @@ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== -"@types/babel__core@^7.1.14": +"@types/babel__core@^7.1.14", "@types/babel__core@^7.18.0": version "7.20.5" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== @@ -3162,6 +3536,13 @@ dependencies: "@babel/types" "^7.20.7" +"@types/babel__traverse@^7.18.0": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.7.tgz#968cdc2366ec3da159f61166428ee40f370e56c2" + integrity sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng== + dependencies: + "@babel/types" "^7.20.7" + "@types/body-parser@*": version "1.19.6" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" @@ -3229,6 +3610,11 @@ "@types/node" "*" "@types/ssh2" "*" +"@types/doctrine@^0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.9.tgz#d86a5f452a15e3e3113b99e39616a9baa0f9863f" + integrity sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA== + "@types/escape-html@^1.0.1": version "1.0.4" resolved "https://registry.yarnpkg.com/@types/escape-html/-/escape-html-1.0.4.tgz#dc7c166b76c7b03b27e32f80edf01d91eb5d9af2" @@ -3433,6 +3819,11 @@ "@types/mapbox__point-geometry" "*" "@types/pbf" "*" +"@types/mdx@^2.0.0": + version "2.0.13" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" + integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw== + "@types/mime@^1": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" @@ -3487,6 +3878,11 @@ resolved "https://registry.yarnpkg.com/@types/pako/-/pako-2.0.3.tgz#b6993334f3af27c158f3fe0dfeeba987c578afb1" integrity sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q== +"@types/parse-json@^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== + "@types/pbf@*", "@types/pbf@^3.0.5": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/pbf/-/pbf-3.0.5.tgz#a9495a58d8c75be4ffe9a0bd749a307715c07404" @@ -3561,6 +3957,11 @@ dependencies: csstype "^3.0.2" +"@types/resolve@^1.20.2": + version "1.20.6" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" + integrity sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ== + "@types/retry@0.12.0": version "0.12.0" resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" @@ -3583,7 +3984,7 @@ resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-3.0.8.tgz#61cc8ed88f93a3c31289c295e6df8ca40be42bdf" integrity sha512-TY1eezMU2zH2ozQoAFAQFOPpvP15g+ZgSfTZt31AUUH/Rxtnz3H+A/Sv1Snw2/amp//omibc+AEkTaA8KUeOLQ== -"@types/semver@^7.5.8": +"@types/semver@^7.3.4", "@types/semver@^7.5.8": version "7.7.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.0.tgz#64c441bdae033b378b6eef7d0c3d77c329b9378e" integrity sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA== @@ -3663,6 +4064,11 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== +"@types/trusted-types@^2.0.2": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + "@types/ua-parser-js@^0.7.36": version "0.7.39" resolved "https://registry.yarnpkg.com/@types/ua-parser-js/-/ua-parser-js-0.7.39.tgz#832c58e460c9435e4e34bb866e85e9146e12cdbb" @@ -3841,7 +4247,7 @@ semver "^7.6.0" ts-api-utils "^2.1.0" -"@typescript-eslint/utils@8.35.0": +"@typescript-eslint/utils@8.35.0", "@typescript-eslint/utils@^8.8.1": version "8.35.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.35.0.tgz#aaf0afab5ab51ea2f1897002907eacd9834606d5" integrity sha512-nqoMu7WWM7ki5tPgLVsmPM8CkqtoPUG6xXGeefM5t4x3XumOEKMoUZPdi+7F+/EotukN4R9OWdmDxN80fqoZeg== @@ -3922,13 +4328,47 @@ "@vector-im/matrix-wysiwyg-wasm@link:../../bindings/wysiwyg-wasm": version "0.0.0" + uid "" "@vector-im/matrix-wysiwyg@2.38.4": version "2.38.4" resolved "https://registry.yarnpkg.com/@vector-im/matrix-wysiwyg/-/matrix-wysiwyg-2.38.4.tgz#fb0001dea01010a1e3ffc7042596e2d001ce9389" integrity sha512-X6ky+1cf33SPdEVd6iTmOKfZZ2mDJv9cz3sHtDhuclS6uitK3QE8td/pmGqBj4ek2Ia4y0mnU61LfxvMry1SMA== dependencies: - "@vector-im/matrix-wysiwyg-wasm" "link:../../bindings/wysiwyg-wasm" + "@vector-im/matrix-wysiwyg-wasm" "link:../../Library/Caches/Yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.4-fb0001dea01010a1e3ffc7042596e2d001ce9389-integrity/node_modules/bindings/wysiwyg-wasm" + +"@vitest/expect@3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.0.9.tgz#b0cb9cd798a131423097cc5a777b699675405fcf" + integrity sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig== + dependencies: + "@vitest/spy" "3.0.9" + "@vitest/utils" "3.0.9" + chai "^5.2.0" + tinyrainbow "^2.0.0" + +"@vitest/pretty-format@3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-3.0.9.tgz#d9c88fe64b4edcdbc88e5bd92c39f9cc8d40930d" + integrity sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA== + dependencies: + tinyrainbow "^2.0.0" + +"@vitest/spy@3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-3.0.9.tgz#c3e5d47ceff7c1cb9fdfb9b2f168056bbc625534" + integrity sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ== + dependencies: + tinyspy "^3.0.2" + +"@vitest/utils@3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-3.0.9.tgz#15da261d8cacd6035dc28a8d3ba38ee39545f82b" + integrity sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng== + dependencies: + "@vitest/pretty-format" "3.0.9" + loupe "^3.1.3" + tinyrainbow "^2.0.0" "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" @@ -4226,7 +4666,7 @@ ansi-escapes@^7.0.0: dependencies: environment "^1.0.0" -ansi-html-community@^0.0.8: +ansi-html-community@0.0.8, ansi-html-community@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== @@ -4469,11 +4909,23 @@ asn1js@^3.0.5: pvutils "^1.1.3" tslib "^2.4.0" +assertion-error@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== + ast-types-flow@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== +ast-types@^0.16.1: + version "0.16.1" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2" + integrity sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg== + dependencies: + tslib "^2.0.1" + astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -4726,6 +5178,13 @@ bcrypt-pbkdf@^1.0.2: dependencies: tweetnacl "^0.14.3" +better-opn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-3.0.2.tgz#f96f35deaaf8f34144a4102651babcf00d1d8817" + integrity sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ== + dependencies: + open "^8.0.4" + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -5007,6 +5466,22 @@ caniuse-lite@1.0.30001724, caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001646, cani resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz#312e163553dd70d2c0fb603d74810c85d8ed94a0" integrity sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA== +case-sensitive-paths-webpack-plugin@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== + +chai@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.2.0.tgz#1358ee106763624114addf84ab02697e411c9c05" + integrity sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw== + dependencies: + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" + chalk@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" @@ -5047,6 +5522,11 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== +check-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" + integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== + chokidar@^3.5.3, chokidar@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" @@ -5094,6 +5574,11 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== +cjs-module-lexer@^1.2.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" + integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== + classnames@^2.2.6, classnames@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" @@ -5236,6 +5721,11 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + commonmark@^0.31.0: version "0.31.2" resolved "https://registry.yarnpkg.com/commonmark/-/commonmark-0.31.2.tgz#9d8d5439c82c9a235154d858a53e1a7965d573a5" @@ -5378,6 +5868,17 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cosmiconfig@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + cosmiconfig@^8.1.3: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" @@ -5509,6 +6010,20 @@ css-has-pseudo@^7.0.2: postcss-selector-parser "^7.0.0" postcss-value-parser "^4.2.0" +css-loader@^6.7.1: + version "6.11.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" + integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.33" + postcss-modules-extract-imports "^3.1.0" + postcss-modules-local-by-default "^4.0.5" + postcss-modules-scope "^3.2.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.5.4" + css-loader@^7.0.0: version "7.1.2" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-7.1.2.tgz#64671541c6efe06b0e22e750503106bdd86880f8" @@ -5795,11 +6310,21 @@ decimal.js@^10.4.3: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.5.0.tgz#0f371c7cf6c4898ce0afb09836db73cd82010f22" integrity sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw== +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + dedent@^1.0.0: version "1.5.3" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== +deep-eql@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -5832,6 +6357,11 @@ define-data-property@^1.0.1, define-data-property@^1.1.4: es-errors "^1.3.0" gopd "^1.0.1" +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + define-lazy-prop@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" @@ -6167,6 +6697,15 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" +endent@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/endent/-/endent-2.1.0.tgz#5aaba698fb569e5e18e69e1ff7a28ff35373cd88" + integrity sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w== + dependencies: + dedent "^0.7.0" + fast-json-parse "^1.0.3" + objectorarray "^1.0.5" + enhanced-resolve@^5.17.1: version "5.18.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" @@ -6306,7 +6845,7 @@ es-iterator-helpers@^1.2.1: iterator.prototype "^1.1.4" safe-array-concat "^1.1.3" -es-module-lexer@^1.2.1: +es-module-lexer@^1.2.1, es-module-lexer@^1.5.0: version "1.7.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== @@ -6344,6 +6883,44 @@ es-to-primitive@^1.3.0: is-date-object "^1.0.5" is-symbol "^1.0.4" +esbuild-register@^3.5.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-3.6.0.tgz#cf270cfa677baebbc0010ac024b823cbf723a36d" + integrity sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg== + dependencies: + debug "^4.3.4" + +"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0": + version "0.25.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.5.tgz#71075054993fdfae76c66586f9b9c1f8d7edd430" + integrity sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ== + optionalDependencies: + "@esbuild/aix-ppc64" "0.25.5" + "@esbuild/android-arm" "0.25.5" + "@esbuild/android-arm64" "0.25.5" + "@esbuild/android-x64" "0.25.5" + "@esbuild/darwin-arm64" "0.25.5" + "@esbuild/darwin-x64" "0.25.5" + "@esbuild/freebsd-arm64" "0.25.5" + "@esbuild/freebsd-x64" "0.25.5" + "@esbuild/linux-arm" "0.25.5" + "@esbuild/linux-arm64" "0.25.5" + "@esbuild/linux-ia32" "0.25.5" + "@esbuild/linux-loong64" "0.25.5" + "@esbuild/linux-mips64el" "0.25.5" + "@esbuild/linux-ppc64" "0.25.5" + "@esbuild/linux-riscv64" "0.25.5" + "@esbuild/linux-s390x" "0.25.5" + "@esbuild/linux-x64" "0.25.5" + "@esbuild/netbsd-arm64" "0.25.5" + "@esbuild/netbsd-x64" "0.25.5" + "@esbuild/openbsd-arm64" "0.25.5" + "@esbuild/openbsd-x64" "0.25.5" + "@esbuild/sunos-x64" "0.25.5" + "@esbuild/win32-arm64" "0.25.5" + "@esbuild/win32-ia32" "0.25.5" + "@esbuild/win32-x64" "0.25.5" + escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" @@ -6510,6 +7087,13 @@ eslint-plugin-react@^7.28.0: string.prototype.matchall "^4.0.12" string.prototype.repeat "^1.0.0" +eslint-plugin-storybook@^9.0.12: + version "9.0.12" + resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-9.0.12.tgz#a9a67ab26d3275ef67fa70d1f1aefbe146b52b88" + integrity sha512-dSzcozoI7tQRqfMODWfxahrRmKWsK88yKSUcO0+s361oYcX7nf8nEu99TQ/wuDLRHh+Zi7E2j43cPMH8gFo8OA== + dependencies: + "@typescript-eslint/utils" "^8.8.1" + eslint-plugin-unicorn@^56.0.0: version "56.0.1" resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz#d10a3df69ba885939075bdc95a65a0c872e940d4" @@ -6630,7 +7214,7 @@ espree@^9.6.0, espree@^9.6.1: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" -esprima@^4.0.0, esprima@^4.0.1: +esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -6828,6 +7412,11 @@ fast-glob@^3.2.9, fast-glob@^3.3.2, fast-glob@^3.3.3: merge2 "^1.3.0" micromatch "^4.0.8" +fast-json-parse@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" + integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== + fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -6990,6 +7579,15 @@ finalhandler@^2.1.0: parseurl "^1.3.3" statuses "^2.0.1" +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -7006,6 +7604,15 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-up@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-7.0.0.tgz#e8dec1455f74f78d888ad65bf7ca13dd2b4e66fb" + integrity sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g== + dependencies: + locate-path "^7.2.0" + path-exists "^5.0.0" + unicorn-magic "^0.1.0" + find-yarn-workspace-root@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" @@ -7078,6 +7685,24 @@ foreground-child@^3.1.0, foreground-child@^3.3.1: cross-spawn "^7.0.6" signal-exit "^4.0.1" +fork-ts-checker-webpack-plugin@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504" + integrity sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg== + dependencies: + "@babel/code-frame" "^7.16.7" + chalk "^4.1.2" + chokidar "^3.5.3" + cosmiconfig "^7.0.1" + deepmerge "^4.2.2" + fs-extra "^10.0.0" + memfs "^3.4.1" + minimatch "^3.0.4" + node-abort-controller "^3.0.1" + schema-utils "^3.1.1" + semver "^7.3.5" + tapable "^2.2.1" + form-data@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.3.tgz#608b1b3f3e28be0fccf5901fc85fb3641e5cf0ae" @@ -7121,6 +7746,15 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^9.0.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -7131,6 +7765,11 @@ fs-extra@^9.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-monkey@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" + integrity sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -7555,7 +8194,7 @@ html-encoding-sniffer@^3.0.0: dependencies: whatwg-encoding "^2.0.0" -html-entities@^2.0.0: +html-entities@^2.0.0, html-entities@^2.1.0: version "2.6.0" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== @@ -7593,7 +8232,7 @@ html-tags@^3.3.1: resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== -html-webpack-plugin@^5.5.3: +html-webpack-plugin@^5.5.0, html-webpack-plugin@^5.5.3: version "5.6.3" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz#a31145f0fee4184d53a794f9513147df1e653685" integrity sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg== @@ -7967,7 +8606,7 @@ is-date-object@^1.0.5, is-date-object@^1.1.0: call-bound "^1.0.2" has-tostringtag "^1.0.2" -is-docker@^2.0.0: +is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== @@ -8187,7 +8826,7 @@ is-weakset@^2.0.3: call-bound "^1.0.3" get-intrinsic "^1.2.6" -is-wsl@^2.1.1: +is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== @@ -8848,7 +9487,7 @@ json5@^1.0.2: dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.2.3: +json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -9081,6 +9720,31 @@ listr2@^8.3.3: rfdc "^1.4.1" wrap-ansi "^9.0.0" +lit-element@^3.3.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.3.3.tgz#10bc19702b96ef5416cf7a70177255bfb17b3209" + integrity sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.1.0" + "@lit/reactive-element" "^1.3.0" + lit-html "^2.8.0" + +lit-html@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.8.0.tgz#96456a4bb4ee717b9a7d2f94562a16509d39bffa" + integrity sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q== + dependencies: + "@types/trusted-types" "^2.0.2" + +lit@^2.1.3: + version "2.8.0" + resolved "https://registry.yarnpkg.com/lit/-/lit-2.8.0.tgz#4d838ae03059bf9cafa06e5c61d8acc0081e974e" + integrity sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA== + dependencies: + "@lit/reactive-element" "^1.6.0" + lit-element "^3.3.0" + lit-html "^2.8.0" + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -9109,6 +9773,13 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +locate-path@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + lodash-es@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" @@ -9192,6 +9863,11 @@ loose-envify@^1.0.0, loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +loupe@^3.1.0, loupe@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.4.tgz#784a0060545cb38778ffb19ccde44d7870d5fdd9" + integrity sha512-wJzkKwJrheKtknCOKNEtDK4iqg/MxmZheEMtSTYvnzRdEYaZzmgH976nenp8WdJRdx5Vc1X/9MO0Oszl6ezeXg== + lower-case@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" @@ -9228,6 +9904,13 @@ magic-string@0.30.8: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" +magic-string@^0.30.5: + version "0.30.17" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + mailpit-api@^1.2.0: version "1.5.0" resolved "https://registry.yarnpkg.com/mailpit-api/-/mailpit-api-1.5.0.tgz#c7006c3650308f4eec1c36f51ac1a66c1e949e5e" @@ -9235,6 +9918,13 @@ mailpit-api@^1.2.0: dependencies: axios "^1.9.0" +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + make-dir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" @@ -9390,6 +10080,13 @@ media-typer@^1.1.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== +memfs@^3.4.1, memfs@^3.4.12: + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== + dependencies: + fs-monkey "^1.0.4" + memfs@^4.6.0: version "4.17.2" resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.17.2.tgz#1f71a6d85c8c53b4f1b388234ed981a690c7e227" @@ -9492,7 +10189,7 @@ mimic-function@^5.0.0: resolved "https://registry.yarnpkg.com/mimic-function/-/mimic-function-5.0.1.tgz#acbe2b3349f99b9deaca7fb70e48b83e94e67076" integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== -min-indent@^1.0.0: +min-indent@^1.0.0, min-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== @@ -9685,6 +10382,11 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" +node-abort-controller@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" + integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== + node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -9820,6 +10522,11 @@ object.values@^1.2.0: define-properties "^1.2.1" es-object-atoms "^1.0.0" +objectorarray@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" + integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== + obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" @@ -9883,6 +10590,15 @@ open@^7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" +open@^8.0.4: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" @@ -9952,6 +10668,13 @@ p-limit@^3.0.2, p-limit@^3.1.0: dependencies: yocto-queue "^0.1.0" +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -9966,6 +10689,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + p-retry@4: version "4.6.2" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" @@ -10079,6 +10809,11 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -10130,6 +10865,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathval@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" + integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== + pbf@^3.2.1, pbf@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.3.0.tgz#1790f3d99118333cc7f498de816028a346ef367f" @@ -10168,7 +10908,7 @@ pirates@^4.0.4: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== -pkg-dir@^4.2.0: +pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== @@ -11146,7 +11886,28 @@ react-clientside-effect@^1.2.7: dependencies: "@babel/runtime" "^7.12.13" -react-dom@^19.0.0: +react-docgen-typescript@^2.2.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz#033428b4a6a639d050ac8baf2a5195c596521713" + integrity sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg== + +react-docgen@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-7.1.1.tgz#a7a8e6b923a945acf0b7325a889ddd74fec74a63" + integrity sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg== + dependencies: + "@babel/core" "^7.18.9" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + "@types/babel__core" "^7.18.0" + "@types/babel__traverse" "^7.18.0" + "@types/doctrine" "^0.0.9" + "@types/resolve" "^1.20.2" + doctrine "^3.0.0" + resolve "^1.22.1" + strip-indent "^4.0.0" + +"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", react-dom@^19.0.0: version "19.1.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.1.0.tgz#133558deca37fa1d682708df8904b25186793623" integrity sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g== @@ -11257,7 +12018,7 @@ react-virtualized@^9.22.5: prop-types "^15.7.2" react-lifecycles-compat "^3.0.4" -react@^19.0.0: +"react@^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", react@^19.0.0: version "19.1.0" resolved "https://registry.yarnpkg.com/react/-/react-19.1.0.tgz#926864b6c48da7627f004795d6cce50e90793b75" integrity sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg== @@ -11340,6 +12101,17 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +recast@^0.23.5: + version "0.23.11" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.11.tgz#8885570bb28cf773ba1dc600da7f502f7883f73f" + integrity sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA== + dependencies: + ast-types "^0.16.1" + esprima "~4.0.0" + source-map "~0.6.1" + tiny-invariant "^1.3.3" + tslib "^2.0.1" + rechoir@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" @@ -11520,7 +12292,7 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.4, resolve@^1.22 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.14.2: +resolve@^1.14.2, resolve@^1.22.1: version "1.22.10" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== @@ -11702,7 +12474,7 @@ scheduler@^0.26.0: resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.26.0.tgz#4ce8a8c2a2095f13ea11bf9a445be50c555d6337" integrity sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA== -schema-utils@^3.0.0: +schema-utils@^3.0.0, schema-utils@^3.1.1: version "3.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -11749,12 +12521,12 @@ selfsigned@^2.4.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.3.0, semver@^6.3.1: +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3: +semver@^7.3.5, semver@^7.3.7, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2, semver@^7.6.3: version "7.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== @@ -12165,6 +12937,23 @@ statuses@2.0.1, statuses@^2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +storybook@^9.0.12: + version "9.0.12" + resolved "https://registry.yarnpkg.com/storybook/-/storybook-9.0.12.tgz#498fea6d185640da162e8cf9bde68a4c288d5ac1" + integrity sha512-mpACe6BMd/M5sqcOiA8NmWIm2zdx0t4ujnA4NTcq4aErdK/KKuU255UM4pO3DIf5zWR5VrDfNV5UaMi/VgE2mA== + dependencies: + "@storybook/global" "^5.0.0" + "@testing-library/jest-dom" "^6.6.3" + "@testing-library/user-event" "^14.6.1" + "@vitest/expect" "3.0.9" + "@vitest/spy" "3.0.9" + better-opn "^3.0.2" + esbuild "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0" + esbuild-register "^3.5.0" + recast "^0.23.5" + semver "^7.6.2" + ws "^8.18.0" + streamx@^2.15.0, streamx@^2.21.0: version "2.22.1" resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.22.1.tgz#c97cbb0ce18da4f4db5a971dc9ab68ff5dc7f5a5" @@ -12349,6 +13138,13 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" +strip-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" + integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== + dependencies: + min-indent "^1.0.1" + strip-json-comments@5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-5.0.2.tgz#14a76abd63b84a6d2419d14f26a0281d0cf6ea46" @@ -12359,6 +13155,11 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +style-loader@^3.3.1: + version "3.3.4" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" + integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== + style-to-js@1.1.16: version "1.1.16" resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.16.tgz#e6bd6cd29e250bcf8fa5e6591d07ced7575dbe7a" @@ -12528,6 +13329,13 @@ svgo@^3.0.2, svgo@^3.3.2: csso "^5.0.5" picocolors "^1.0.0" +swc-loader@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/swc-loader/-/swc-loader-0.2.6.tgz#bf0cba8eeff34bb19620ead81d1277fefaec6bc8" + integrity sha512-9Zi9UP2YmDpgmQVbyOPJClY0dwf58JDyDMQ7uRc4krmc72twNI2fvlBWHLqVekBpPc7h5NJkGVT1zNDxFrqhvg== + dependencies: + "@swc/counter" "^0.1.3" + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -12617,7 +13425,7 @@ temporal-spec@0.3.0: resolved "https://registry.yarnpkg.com/temporal-spec/-/temporal-spec-0.3.0.tgz#8c4210c575fb28ba0a1c2e02ad68d1be5956a11f" integrity sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ== -terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.9: +terser-webpack-plugin@^5.3.1, terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.9: version "5.3.14" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== @@ -12700,7 +13508,7 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== -tiny-invariant@^1.0.6: +tiny-invariant@^1.0.6, tiny-invariant@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== @@ -12726,6 +13534,16 @@ tinyqueue@^3.0.0: resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-3.0.0.tgz#101ea761ccc81f979e29200929e78f1556e3661e" integrity sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g== +tinyrainbow@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-2.0.0.tgz#9509b2162436315e80e3eee0fcce4474d2444294" + integrity sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw== + +tinyspy@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" + integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -12816,6 +13634,11 @@ ts-api-utils@^2.0.1, ts-api-utils@^2.1.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.1.0.tgz#595f7094e46eed364c13fd23e75f9513d29baf91" integrity sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== +ts-dedent@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + ts-node@^10.9.1: version "10.9.2" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" @@ -12845,7 +13668,16 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.0: +tsconfig-paths@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -13027,6 +13859,11 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== +unicorn-magic@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4" + integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ== + universalify@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" @@ -13052,6 +13889,14 @@ unplugin@1.0.1: webpack-sources "^3.2.3" webpack-virtual-modules "^0.5.0" +unplugin@^1.3.1: + version "1.16.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.16.1.tgz#a844d2e3c3b14a4ac2945c42be80409321b61199" + integrity sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w== + dependencies: + acorn "^8.14.0" + webpack-virtual-modules "^0.6.2" + update-browserslist-db@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" @@ -13310,6 +14155,17 @@ webpack-cli@^6.0.0: rechoir "^0.8.0" webpack-merge "^6.0.1" +webpack-dev-middleware@^6.1.2: + version "6.1.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz#79f4103f8c898564c9e96c3a9c2422de50f249bc" + integrity sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw== + dependencies: + colorette "^2.0.10" + memfs "^3.4.12" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + webpack-dev-middleware@^7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz#40e265a3d3d26795585cff8207630d3a8ff05877" @@ -13356,6 +14212,15 @@ webpack-dev-server@^5.0.0: webpack-dev-middleware "^7.4.2" ws "^8.18.0" +webpack-hot-middleware@^2.25.1: + version "2.26.1" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz#87214f1e3f9f3acab9271fef9e6ed7b637d719c0" + integrity sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A== + dependencies: + ansi-html-community "0.0.8" + html-entities "^2.1.0" + strip-ansi "^6.0.0" + webpack-merge@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-6.0.1.tgz#50c776868e080574725abc5869bd6e4ef0a16c6a" @@ -13391,7 +14256,12 @@ webpack-virtual-modules@^0.5.0: resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz#362f14738a56dae107937ab98ea7062e8bdd3b6c" integrity sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw== -webpack@^5.89.0: +webpack-virtual-modules@^0.6.0, webpack-virtual-modules@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8" + integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ== + +webpack@5, webpack@^5.89.0: version "5.99.9" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.99.9.tgz#d7de799ec17d0cce3c83b70744b4aedb537d8247" integrity sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg== @@ -13667,6 +14537,11 @@ yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + yaml@^2.2.2, yaml@^2.3.3, yaml@^2.7.0, yaml@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.0.tgz#15f8c9866211bdc2d3781a0890e44d4fa1a5fff6" @@ -13725,6 +14600,11 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yocto-queue@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" + integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg== + zip-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-6.0.1.tgz#e141b930ed60ccaf5d7fa9c8260e0d1748a2bbfb" From 3d724ffa841882871e16a7593a46f80ab5ab905f Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Jun 2025 16:37:47 +0100 Subject: [PATCH 10/30] Add TextualEvent component to storybook --- .storybook/main.ts | 2 +- jest.config.ts | 2 +- .../event-tiles/TextualEvent/TextualEvent.stories.tsx | 7 +++++-- .../event-tiles/TextualEvent/TextualEvent.tsx | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index 27703dbd687..9fbf75a4e13 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,7 +1,7 @@ import type { StorybookConfig } from "@storybook/react-webpack5"; const config: StorybookConfig = { - stories: ["../src/shared/**/*.mdx", "../src/shared/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + stories: ["../src/shared-components/**/*.mdx", "../src/shared-components/**/*.stories.@(js|jsx|mjs|ts|tsx)"], addons: [ "@storybook/addon-webpack5-compiler-swc", "@storybook/addon-docs", diff --git a/jest.config.ts b/jest.config.ts index ad31f2fecc4..f40ac487a25 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -17,7 +17,7 @@ const config: Config = { // This is needed to be able to load dual CJS/ESM WASM packages e.g. rust crypto & matrix-wywiwyg customExportConditions: ["browser", "node"], }, - testMatch: ["/test/**/*-test.[tj]s?(x)"], + testMatch: ["/test/**/*-test.[tj]s?(x)", "/src/shared-components/**/*.test.[t]s?(x)"], globalSetup: "/test/globalSetup.ts", setupFiles: ["jest-canvas-mock", "web-streams-polyfill/polyfill"], setupFilesAfterEnv: ["/test/setupTests.ts"], diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx index c16f29c35e1..8fda56fad43 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx @@ -9,12 +9,15 @@ import React from "react"; import { type Meta, type StoryFn } from "@storybook/react"; import { TextualEvent as TextualEventComponent } from "./TextualEvent"; +import { MockViewModel } from "../../MockViewModel"; export default { - title: "Icon/BigIcon", + title: "Event/TextualEvent", component: TextualEventComponent, tags: ["autodocs"], - args: {}, + args: { + vm: new MockViewModel("Dummy textual event text"), + }, } as Meta; const Template: StoryFn = (args) => ; diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx index cc351a3b3c5..1dec80905ec 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.tsx @@ -12,7 +12,7 @@ import { useViewModel } from "../../useViewModel"; export type TextualEventViewSnapshot = string | ReactNode; -interface Props { +export interface Props { vm: ViewModel; } From 11f9849e516b8b201b0989ea9d53c712c0938b58 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Jun 2025 16:38:13 +0100 Subject: [PATCH 11/30] Add mock view model & snapshot --- src/shared-components/MockViewModel.ts | 21 +++++++++++++++++++ .../__snapshots__/TextualEvent.test.tsx.snap | 11 ++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/shared-components/MockViewModel.ts create mode 100644 src/shared-components/event-tiles/TextualEvent/__snapshots__/TextualEvent.test.tsx.snap diff --git a/src/shared-components/MockViewModel.ts b/src/shared-components/MockViewModel.ts new file mode 100644 index 00000000000..47d795b543d --- /dev/null +++ b/src/shared-components/MockViewModel.ts @@ -0,0 +1,21 @@ +/* +Copyright 2025 New Vector Ltd. + +SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +Please see LICENSE files in the repository root for full details. +*/ + +/** + * A mock view model that returns a static snapshot passed in the constructor, with no updates. + */ +export class MockViewModel { + public constructor(private snapshot: T) {} + + public getSnapshot = (): T => { + return this.snapshot; + }; + + public subscribe(listener: () => void): () => void { + return () => undefined; + } +} diff --git a/src/shared-components/event-tiles/TextualEvent/__snapshots__/TextualEvent.test.tsx.snap b/src/shared-components/event-tiles/TextualEvent/__snapshots__/TextualEvent.test.tsx.snap new file mode 100644 index 00000000000..186e5f0afd8 --- /dev/null +++ b/src/shared-components/event-tiles/TextualEvent/__snapshots__/TextualEvent.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TextualEvent renders a textual event 1`] = ` +
+
+ Dummy textual event text +
+
+`; From 470965651075df4fb84fabd2a97864f0b0bc7cc3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 30 Jun 2025 16:39:26 +0100 Subject: [PATCH 12/30] Remove old style stories entry --- .storybook/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index 9fbf75a4e13..b972a5a1e7c 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,7 +1,7 @@ import type { StorybookConfig } from "@storybook/react-webpack5"; const config: StorybookConfig = { - stories: ["../src/shared-components/**/*.mdx", "../src/shared-components/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + stories: ["../src/shared-components/**/*.stories.@(js|jsx|mjs|ts|tsx)"], addons: [ "@storybook/addon-webpack5-compiler-swc", "@storybook/addon-docs", From 9318006b219e99fd8e5b5a2f2240f7ef4a114b66 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 1 Jul 2025 14:55:12 +0100 Subject: [PATCH 13/30] Change import --- .../event-tiles/TextualEvent/TextualEvent.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx index 8fda56fad43..cbfd29e5022 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx @@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { type Meta, type StoryFn } from "@storybook/react"; +import { type Meta, type StoryFn } from "@storybook/react-webpack5"; import { TextualEvent as TextualEventComponent } from "./TextualEvent"; import { MockViewModel } from "../../MockViewModel"; From a9364332b3bbc6324589904a472492f051ad1f3b Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 1 Jul 2025 14:58:15 +0100 Subject: [PATCH 14/30] Change import --- .../event-tiles/TextualEvent/TextualEvent.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx index 04ea727f978..de983ed6374 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { composeStories } from "@storybook/react"; +import { composeStories } from "@storybook/react-webpack5"; import { render } from "jest-matrix-react"; import React from "react"; From 472de3bd144a880be0f3aa5327d660dca8e61735 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 1 Jul 2025 15:12:39 +0100 Subject: [PATCH 15/30] Prettier --- .storybook/preview.css | 2 +- tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.storybook/preview.css b/.storybook/preview.css index c0d2b88a84c..0afe1649f9e 100644 --- a/.storybook/preview.css +++ b/.storybook/preview.css @@ -1,3 +1,3 @@ .docs-story { - background: var(--cpd-color-bg-canvas-default); + background: var(--cpd-color-bg-canvas-default); } diff --git a/tsconfig.json b/tsconfig.json index 178cc1be40c..55e7ae925b5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,7 +27,7 @@ "./test/**/*.ts", "./test/**/*.tsx", "./scripts/*.ts", - "./declaration.d.ts", + "./declaration.d.ts" ], "ts-node": { "files": true, From 073d97e261701e3bd99584a24d58214abba9852e Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 1 Jul 2025 15:41:15 +0100 Subject: [PATCH 16/30] Add paxckage patch to @types/mdx for React 19 compat --- patches/@types+mdx+2.0.13.patch | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 patches/@types+mdx+2.0.13.patch diff --git a/patches/@types+mdx+2.0.13.patch b/patches/@types+mdx+2.0.13.patch new file mode 100644 index 00000000000..d3d02974f73 --- /dev/null +++ b/patches/@types+mdx+2.0.13.patch @@ -0,0 +1,46 @@ +diff --git a/node_modules/@types/mdx/types.d.ts b/node_modules/@types/mdx/types.d.ts +index 498bb69..4e89216 100644 +--- a/node_modules/@types/mdx/types.d.ts ++++ b/node_modules/@types/mdx/types.d.ts +@@ -5,7 +5,7 @@ + */ + // @ts-ignore JSX runtimes may optionally define JSX.ElementType. The MDX types need to work regardless whether this is + // defined or not. +-type ElementType = any extends JSX.ElementType ? never : JSX.ElementType; ++type ElementType = any extends JSX.ElementType ? never : React.JSX.ElementType; + + /** + * This matches any function component types that ar part of `ElementType`. +@@ -20,12 +20,12 @@ type ClassElementType = Extract) => + /** + * A valid JSX string component. + */ +-type StringComponent = Extract; ++type StringComponent = Extract; + + /** + * A JSX element returned by MDX content. + */ +-export type Element = JSX.Element; ++export type Element = React.JSX.Element; + + /** + * A valid JSX function component. +@@ -44,7 +44,7 @@ type FunctionComponent = ElementType extends never + */ + type ClassComponent = ElementType extends never + // If JSX.ElementType isn’t defined, the valid return type is a constructor that returns JSX.ElementClass +- ? new(props: Props) => JSX.ElementClass ++ ? new(props: Props) => React.JSX.ElementClass + : ClassElementType extends never + // If JSX.ElementType is defined, but doesn’t allow constructors, function components are disallowed. + ? never +@@ -70,7 +70,7 @@ interface NestedMDXComponents { + export type MDXComponents = + & NestedMDXComponents + & { +- [Key in StringComponent]?: Component; ++ [Key in StringComponent]?: Component; + } + & { + /** From 862aaff4685d0643b6efc15b291349868c3c246e Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 3 Jul 2025 13:46:29 +0100 Subject: [PATCH 17/30] Pass getSnapshot as getServerSnapshot too --- src/shared-components/useViewModel.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/shared-components/useViewModel.ts b/src/shared-components/useViewModel.ts index c714513ae59..22269ffcd0c 100644 --- a/src/shared-components/useViewModel.ts +++ b/src/shared-components/useViewModel.ts @@ -10,5 +10,7 @@ import { useSyncExternalStore } from "react"; import { type ViewModel } from "./ViewModel"; export function useViewModel(vm: ViewModel): T { - return useSyncExternalStore(vm.subscribe, vm.getSnapshot); + // We need to pass the same getSnapshot function as getServerSnapshot as this + // is used when making the HTML chat export. + return useSyncExternalStore(vm.subscribe, vm.getSnapshot, vm.getSnapshot); } From 82d08df2976f405d7dd17711b29ef8165cccb298 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 3 Jul 2025 15:14:47 +0100 Subject: [PATCH 18/30] Maybe make sonar regognise tests as tests --- sonar-project.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index d95f46460bd..c19988ca52f 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -5,7 +5,8 @@ sonar.organization=element-hq #sonar.sourceEncoding=UTF-8 sonar.sources=src,res -sonar.tests=test,playwright +sonar.tests=test,playwright.src +sonar.test.inclusions=test/*,playwright/*,src/**/*.test.tsx sonar.exclusions=__mocks__,docs,element.io,nginx sonar.cpd.exclusions=src/i18n/strings/*.json From b1edabe384887aca85ba89ef06b98c00765b6072 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 3 Jul 2025 15:31:57 +0100 Subject: [PATCH 19/30] Typo --- sonar-project.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonar-project.properties b/sonar-project.properties index c19988ca52f..23333a43cce 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -5,7 +5,7 @@ sonar.organization=element-hq #sonar.sourceEncoding=UTF-8 sonar.sources=src,res -sonar.tests=test,playwright.src +sonar.tests=test,playwright,src sonar.test.inclusions=test/*,playwright/*,src/**/*.test.tsx sonar.exclusions=__mocks__,docs,element.io,nginx From 32850072243adc669b0085a2674a56d223da4734 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 3 Jul 2025 17:09:08 +0100 Subject: [PATCH 20/30] Use storybook reacvt-vite There's no reason to use the react-webpack plugin just because our app is stuck on webpack, it just means we have vite as a dependency too. --- .storybook/main.ts | 5 +- package.json | 4 +- .../TextualEvent/TextualEvent.stories.tsx | 2 +- .../TextualEvent/TextualEvent.test.tsx | 2 +- yarn.lock | 619 ++++++++---------- 5 files changed, 281 insertions(+), 351 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index b972a5a1e7c..95dd14be008 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,9 +1,8 @@ -import type { StorybookConfig } from "@storybook/react-webpack5"; +import type { StorybookConfig } from "@storybook/react-vite"; const config: StorybookConfig = { stories: ["../src/shared-components/**/*.stories.@(js|jsx|mjs|ts|tsx)"], addons: [ - "@storybook/addon-webpack5-compiler-swc", "@storybook/addon-docs", "@storybook/addon-designs", { @@ -35,7 +34,7 @@ const config: StorybookConfig = { }, }, ], - framework: "@storybook/react-webpack5", + framework: "@storybook/react-vite", core: { disableTelemetry: true, }, diff --git a/package.json b/package.json index da03320ca42..aee8f9b401e 100644 --- a/package.json +++ b/package.json @@ -192,8 +192,7 @@ "@storybook/addon-designs": "^10.0.1", "@storybook/addon-docs": "^9.0.12", "@storybook/addon-styling-webpack": "^2.0.0", - "@storybook/addon-webpack5-compiler-swc": "^3.0.0", - "@storybook/react-webpack5": "^9.0.12", + "@storybook/react-vite": "^9.0.15", "@stylistic/eslint-plugin": "^4.0.0", "@svgr/webpack": "^8.0.0", "@testing-library/dom": "^10.4.0", @@ -303,6 +302,7 @@ "ts-node": "^10.9.1", "typescript": "5.8.3", "util": "^0.12.5", + "vite": "^7.0.1", "web-streams-polyfill": "^4.0.0", "webpack": "^5.89.0", "webpack-bundle-analyzer": "^4.8.0", diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx index cbfd29e5022..1746bc14b23 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.stories.tsx @@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details. */ import React from "react"; -import { type Meta, type StoryFn } from "@storybook/react-webpack5"; +import { type Meta, type StoryFn } from "@storybook/react-vite"; import { TextualEvent as TextualEventComponent } from "./TextualEvent"; import { MockViewModel } from "../../MockViewModel"; diff --git a/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx b/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx index de983ed6374..b1ef5e8f525 100644 --- a/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx +++ b/src/shared-components/event-tiles/TextualEvent/TextualEvent.test.tsx @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { composeStories } from "@storybook/react-webpack5"; +import { composeStories } from "@storybook/react-vite"; import { render } from "jest-matrix-react"; import React from "react"; diff --git a/yarn.lock b/yarn.lock index b56264946d1..a5a0fe505a2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,7 +34,7 @@ dependencies: axe-core "~4.10.3" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.27.1": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== @@ -2252,6 +2252,15 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@joshwooding/vite-plugin-react-docgen-typescript@0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.6.1.tgz#f630b93ed13d5d07483c0ead42db793053b364a9" + integrity sha512-J4BaTocTOYFkMHIra1JDWrMWpNmBl4EkplIwHEsV8aeUOtdWjwSnln9U7twjMFTAEB7mptNtSKyVi1Y2W9sDJw== + dependencies: + glob "^10.0.0" + magic-string "^0.30.0" + react-docgen-typescript "^2.2.2" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.8" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" @@ -2931,6 +2940,115 @@ resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.0.tgz#f817d1d3265ac5415dadc67edab30ae196696438" integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg== +"@rollup/pluginutils@^5.0.2": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.2.0.tgz#eac25ca5b0bdda4ba735ddaca5fbf26bd435f602" + integrity sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^4.0.2" + +"@rollup/rollup-android-arm-eabi@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.1.tgz#f768e3b2b0e6b55c595d7a053652c06413713983" + integrity sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w== + +"@rollup/rollup-android-arm64@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.1.tgz#40379fd5501cfdfd7d8f86dfa1d3ce8d3a609493" + integrity sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ== + +"@rollup/rollup-darwin-arm64@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.1.tgz#972c227bc89fe8a38a3f0c493e1966900e4e1ff7" + integrity sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg== + +"@rollup/rollup-darwin-x64@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.1.tgz#96c919dcb87a5aa7dec5f7f77d90de881e578fdd" + integrity sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw== + +"@rollup/rollup-freebsd-arm64@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.1.tgz#d199d8eaef830179c0c95b7a6e5455e893d1102c" + integrity sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA== + +"@rollup/rollup-freebsd-x64@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.1.tgz#cab01f9e06ca756c1fabe87d64825ae016af4713" + integrity sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw== + +"@rollup/rollup-linux-arm-gnueabihf@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.1.tgz#f6f1c42036dba0e58dc2315305429beff0d02c78" + integrity sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ== + +"@rollup/rollup-linux-arm-musleabihf@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.1.tgz#1157e98e740facf858993fb51431dce3a4a96239" + integrity sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw== + +"@rollup/rollup-linux-arm64-gnu@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.1.tgz#b39db73f8a4c22e7db31a4f3fd45170105f33265" + integrity sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ== + +"@rollup/rollup-linux-arm64-musl@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.1.tgz#4043398049fe4449c1485312d1ae9ad8af4056dd" + integrity sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g== + +"@rollup/rollup-linux-loongarch64-gnu@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.1.tgz#855a80e7e86490da15a85dcce247dbc25265bc08" + integrity sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew== + +"@rollup/rollup-linux-powerpc64le-gnu@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.1.tgz#8cf843cb7ab1d42e1dda680937cf0a2db6d59047" + integrity sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA== + +"@rollup/rollup-linux-riscv64-gnu@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.1.tgz#287c085472976c8711f16700326f736a527f2f38" + integrity sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw== + +"@rollup/rollup-linux-riscv64-musl@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.1.tgz#095ad5e53a54ba475979f1b3226b92440c95c892" + integrity sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg== + +"@rollup/rollup-linux-s390x-gnu@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.1.tgz#a3dec8281d8f2aef1703e48ebc65d29fe847933c" + integrity sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw== + +"@rollup/rollup-linux-x64-gnu@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.1.tgz#4b211e6fd57edd6a134740f4f8e8ea61972ff2c5" + integrity sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw== + +"@rollup/rollup-linux-x64-musl@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.1.tgz#3ecbf8e21b4157e57bb15dc6837b6db851f9a336" + integrity sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g== + +"@rollup/rollup-win32-arm64-msvc@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.1.tgz#d4aae38465b2ad200557b53c8c817266a3ddbfd0" + integrity sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg== + +"@rollup/rollup-win32-ia32-msvc@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.1.tgz#0258e8ca052abd48b23fd6113360fa0cd1ec3e23" + integrity sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A== + +"@rollup/rollup-win32-x64-msvc@4.44.1": + version "4.44.1" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.1.tgz#1c982f6a5044ffc2a35cd754a0951bdcb44d5ba0" + integrity sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug== + "@rrweb/types@^2.0.0-alpha.18": version "2.0.0-alpha.18" resolved "https://registry.yarnpkg.com/@rrweb/types/-/types-2.0.0-alpha.18.tgz#e1d9af844cebbf30a2be8808f6cf64f5df3e7f50" @@ -3113,40 +3231,12 @@ resolved "https://registry.yarnpkg.com/@storybook/addon-styling-webpack/-/addon-styling-webpack-2.0.0.tgz#3e854c82a835a6df439a69e307f337b39b4a4cab" integrity sha512-N8jWhWnk3/nbL4P9zl0OEV/47P0Cxn/kPzSHjdAClyDYnqj9jI6upeLsraZgIV9Ro3QSeqeIloeXb1zMasWpOw== -"@storybook/addon-webpack5-compiler-swc@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@storybook/addon-webpack5-compiler-swc/-/addon-webpack5-compiler-swc-3.0.0.tgz#78388c5d8a8375fe99f3b964057bc0402274e7d5" - integrity sha512-qkQwQEvHlxwPCHz/xakGfXJusEa1gKMw7enELh6QGopblfN3rMiV084boqiIqBReqWTasSwHOqvuElAu0NQ+8w== - dependencies: - "@swc/core" "^1.10.8" - swc-loader "^0.2.6" - -"@storybook/builder-webpack5@9.0.12": - version "9.0.12" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-9.0.12.tgz#c050ef1f4f282aa2afb121f4720e066c504c7828" - integrity sha512-zfmGYZjDppYPZZgSwW9ZRfIrCvshZcLombKmVEodlt/RMs5N5zaTCNf5p7+Z1BBcRpH5HXHWjwmrlobW6LzsLg== - dependencies: - "@storybook/core-webpack" "9.0.12" - case-sensitive-paths-webpack-plugin "^2.4.0" - cjs-module-lexer "^1.2.3" - css-loader "^6.7.1" - es-module-lexer "^1.5.0" - fork-ts-checker-webpack-plugin "^8.0.0" - html-webpack-plugin "^5.5.0" - magic-string "^0.30.5" - style-loader "^3.3.1" - terser-webpack-plugin "^5.3.1" - ts-dedent "^2.0.0" - webpack "5" - webpack-dev-middleware "^6.1.2" - webpack-hot-middleware "^2.25.1" - webpack-virtual-modules "^0.6.0" - -"@storybook/core-webpack@9.0.12": - version "9.0.12" - resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-9.0.12.tgz#d2a09f9b7eb5b6e87226d05661c0cc6215cbf72f" - integrity sha512-soFgpQh8pfba94YjkFBMNO4460/NEhdWe2WUPJs5drz2tOyGSElYma9KKjkbn+SQtr4qG0Xu7P56e8DJMXiMDg== +"@storybook/builder-vite@9.0.15": + version "9.0.15" + resolved "https://registry.yarnpkg.com/@storybook/builder-vite/-/builder-vite-9.0.15.tgz#be8f25e5e2e9224a0379c58acc2f52298283c383" + integrity sha512-ogPec1V+e3MgTY5DBlq/6hBBui0Y4TmolYQh0eL3cATHrwZlwkTTDWQfsOnMALd5w+4Jq8n0gk0cQgR5rh1FHw== dependencies: + "@storybook/csf-plugin" "9.0.15" ts-dedent "^2.0.0" "@storybook/csf-plugin@9.0.12": @@ -3156,6 +3246,13 @@ dependencies: unplugin "^1.3.1" +"@storybook/csf-plugin@9.0.15": + version "9.0.15" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-9.0.15.tgz#bb9c2291a6dbefb33d8494689b2ebdec75b6d74a" + integrity sha512-KszyGjrocMiNbkmpBGARF1ugLYMVaw1J8Z31kmwTHsMgMZwAKcOsofJ0fPgFno0yV59DUVkWxVBdPs9V0hhvxA== + dependencies: + unplugin "^1.3.1" + "@storybook/global@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" @@ -3166,56 +3263,38 @@ resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.4.0.tgz#7cf7ab3dfb41943930954c4ef493a73798d8b31d" integrity sha512-Td73IeJxOyalzvjQL+JXx72jlIYHgs+REaHiREOqfpo3A2AYYG71AUbcv+lg7mEDIweKVCxsMQ0UKo634c8XeA== -"@storybook/preset-react-webpack@9.0.12": - version "9.0.12" - resolved "https://registry.yarnpkg.com/@storybook/preset-react-webpack/-/preset-react-webpack-9.0.12.tgz#3a39887398f7c11b41fa55d44e6f31f82a2fa4e2" - integrity sha512-Tl3Qrll29dwltI4lP15zbeSXqikKa4Ucp6NKf4+W/4adzOqGRjj/bIzO3FsIPoGNs4wfy5DsOgUUPHxI4Jx97w== - dependencies: - "@storybook/core-webpack" "9.0.12" - "@storybook/react-docgen-typescript-plugin" "1.0.6--canary.9.0c3f3b7.0" - "@types/semver" "^7.3.4" - find-up "^7.0.0" - magic-string "^0.30.5" - react-docgen "^7.1.1" - resolve "^1.22.8" - semver "^7.3.7" - tsconfig-paths "^4.2.0" - webpack "5" - -"@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0": - version "1.0.6--canary.9.0c3f3b7.0" - resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz#7f10f3c641f32e4513a8b6ffb5036933e7059534" - integrity sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q== - dependencies: - debug "^4.1.1" - endent "^2.0.1" - find-cache-dir "^3.3.1" - flat-cache "^3.0.4" - micromatch "^4.0.2" - react-docgen-typescript "^2.2.2" - tslib "^2.0.0" - "@storybook/react-dom-shim@9.0.12": version "9.0.12" resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-9.0.12.tgz#745d7ba464ef087ce8489c5ffb80ad5bc9bfe83d" integrity sha512-OMBitzkJRga/UJF1ScSnaxgBSlAVePCK8wzPkGDn0MmsjZ4oDWuNZeKnVO1+tb6n2rZHws7RmKGxHzHAZTY+zQ== -"@storybook/react-webpack5@^9.0.12": - version "9.0.12" - resolved "https://registry.yarnpkg.com/@storybook/react-webpack5/-/react-webpack5-9.0.12.tgz#15180a58eccd2287e2df1fd20f74f486e150150e" - integrity sha512-SHVwmmnodGcvLn0pclPu4P9b3qexUXTFPsGmtjQnGObZ3AqhjWiei8h4pYtX8m8zhu419QWevykJq6oWvYzHdA== +"@storybook/react-dom-shim@9.0.15": + version "9.0.15" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-9.0.15.tgz#5c98ad2a3ead9c4ac1136d75d4e1e08e25fc6443" + integrity sha512-X5VlYKoZSIMU9HEshIwtNzp41nPt4kiJtJ2c5HzFa5F6M8rEHM5n059CGcCZQqff3FnZtK/y6v/kCVZO+8oETA== + +"@storybook/react-vite@^9.0.15": + version "9.0.15" + resolved "https://registry.yarnpkg.com/@storybook/react-vite/-/react-vite-9.0.15.tgz#4eda755a03a06a8b321220e9be61cc241ba91f8b" + integrity sha512-OOAywn5x2Ged3LD84+TMwpjZUelFg7Wb8eHkgHE2SzM20XiZrhoKvreqxlzbfey3weBl+bKNhsiWF9BluT8YHg== dependencies: - "@storybook/builder-webpack5" "9.0.12" - "@storybook/preset-react-webpack" "9.0.12" - "@storybook/react" "9.0.12" + "@joshwooding/vite-plugin-react-docgen-typescript" "0.6.1" + "@rollup/pluginutils" "^5.0.2" + "@storybook/builder-vite" "9.0.15" + "@storybook/react" "9.0.15" + find-up "^7.0.0" + magic-string "^0.30.0" + react-docgen "^8.0.0" + resolve "^1.22.8" + tsconfig-paths "^4.2.0" -"@storybook/react@9.0.12": - version "9.0.12" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-9.0.12.tgz#7dd2c0312d29f83cc620f4285ec5af028f922d8f" - integrity sha512-rDrf5MDfsguNDTSOfGqhAjQDhp3jDMdzAoCqLjQ75M647C8nsv9i+fftO3k0rMxIJRrESpZWqVZ4tsjOX+J3DA== +"@storybook/react@9.0.15": + version "9.0.15" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-9.0.15.tgz#e59913879baf6043dd2828cf1818d33f8839588c" + integrity sha512-hewpSH8Ij4Bg7S9Tfw7ecfGPv7YDycRxsfpsDX7Mw3JhLuCdqjpmmTL2RgoNojg7TAW3FPdixcgQi/b4PH50ag== dependencies: "@storybook/global" "^5.0.0" - "@storybook/react-dom-shim" "9.0.12" + "@storybook/react-dom-shim" "9.0.15" "@stylistic/eslint-plugin@^4.0.0": version "4.4.1" @@ -3334,87 +3413,6 @@ "@svgr/plugin-jsx" "8.1.0" "@svgr/plugin-svgo" "8.1.0" -"@swc/core-darwin-arm64@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.12.1.tgz#a2aa56b644472f12e66357701ac8120cc331ed01" - integrity sha512-nUjWVcJ3YS2N40ZbKwYO2RJ4+o2tWYRzNOcIQp05FqW0+aoUCVMdAUUzQinPDynfgwVshDAXCKemY8X7nN5MaA== - -"@swc/core-darwin-x64@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.12.1.tgz#075049a2cfb386c3e533b535fd0ec4d1c851b3af" - integrity sha512-OGm4a4d3OeJn+tRt8H/eiHgTFrJbS6r8mi/Ob65tAEXZGHN900T2kR7c5ALr0V2hBOQ8BfhexwPoQlGQP/B95w== - -"@swc/core-linux-arm-gnueabihf@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.12.1.tgz#53ace44bc470eb96fc5115e2f83d240b11be98ae" - integrity sha512-76YeeQKyK0EtNkQiNBZ0nbVGooPf9IucY0WqVXVpaU4wuG7ZyLEE2ZAIgXafIuzODGQoLfetue7I8boMxh1/MA== - -"@swc/core-linux-arm64-gnu@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.12.1.tgz#d120abbb46d8d7f6b0ab831ee7868651ece87cd1" - integrity sha512-BxJDIJPq1+aCh9UsaSAN6wo3tuln8UhNXruOrzTI8/ElIig/3sAueDM6Eq7GvZSGGSA7ljhNATMJ0elD7lFatQ== - -"@swc/core-linux-arm64-musl@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.12.1.tgz#468732c327c657fde5a486daf910cbf60391a6a2" - integrity sha512-NhLdbffSXvY0/FwUSAl4hKBlpe5GHQGXK8DxTo3HHjLsD9sCPYieo3vG0NQoUYAy4ZUY1WeGjyxeq4qZddJzEQ== - -"@swc/core-linux-x64-gnu@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.12.1.tgz#fda705587c211400017f163a45c24706b42649ba" - integrity sha512-CrYnV8SZIgArQ9LKH0xEF95PKXzX9WkRSc5j55arOSBeDCeDUQk1Bg/iKdnDiuj5HC1hZpvzwMzSBJjv+Z70jA== - -"@swc/core-linux-x64-musl@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.12.1.tgz#c8d05ecdabbc23598d6bd880a2202eade55af9c9" - integrity sha512-BQMl3d0HaGB0/h2xcKlGtjk/cGRn2tnbsaChAKcjFdCepblKBCz1pgO/mL7w5iXq3s57wMDUn++71/a5RAkZOA== - -"@swc/core-win32-arm64-msvc@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.12.1.tgz#dea562db2529d82bedcb71be1030a01b88707fc6" - integrity sha512-b7NeGnpqTfmIGtUqXBl0KqoSmOnH64nRZoT5l4BAGdvwY7nxitWR94CqZuwyLPty/bLywmyDA9uO12Kvgb3+gg== - -"@swc/core-win32-ia32-msvc@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.12.1.tgz#8e2be4875df831b2c7d340bed0688094a914b03c" - integrity sha512-iU/29X2D7cHBp1to62cUg/5Xk8K+lyOJiKIGGW5rdzTW/c2zz3d/ehgpzVP/rqC4NVr88MXspqHU4il5gmDajw== - -"@swc/core-win32-x64-msvc@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.12.1.tgz#f0cf5136844cd42d93a6bff7c1be2b8cb1c71174" - integrity sha512-+Zh+JKDwiFqV5N9yAd2DhYVGPORGh9cfenu1ptr9yge+eHAf7vZJcC3rnj6QMR1QJh0Y5VC9+YBjRFjZVA7XDw== - -"@swc/core@^1.10.8": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.12.1.tgz#373759c60a3bf44a0dc02d411d31c31fbfd7c64b" - integrity sha512-aKXdDTqxTVFl/bKQZ3EQUjEMBEoF6JBv29moMZq0kbVO43na6u/u+3Vcbhbrh+A2N0X5OL4RaveuWfAjEgOmeA== - dependencies: - "@swc/counter" "^0.1.3" - "@swc/types" "^0.1.23" - optionalDependencies: - "@swc/core-darwin-arm64" "1.12.1" - "@swc/core-darwin-x64" "1.12.1" - "@swc/core-linux-arm-gnueabihf" "1.12.1" - "@swc/core-linux-arm64-gnu" "1.12.1" - "@swc/core-linux-arm64-musl" "1.12.1" - "@swc/core-linux-x64-gnu" "1.12.1" - "@swc/core-linux-x64-musl" "1.12.1" - "@swc/core-win32-arm64-msvc" "1.12.1" - "@swc/core-win32-ia32-msvc" "1.12.1" - "@swc/core-win32-x64-msvc" "1.12.1" - -"@swc/counter@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" - integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== - -"@swc/types@^0.1.23": - version "0.1.23" - resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.23.tgz#7eabf88b9cfd929253859c562ae95982ee04b4e8" - integrity sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw== - dependencies: - "@swc/counter" "^0.1.3" - "@testcontainers/postgresql@^11.0.0": version "11.0.3" resolved "https://registry.yarnpkg.com/@testcontainers/postgresql/-/postgresql-11.0.3.tgz#53387b2706ef519afdbe9064c025f51a62b4471d" @@ -3641,6 +3639,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8" integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ== +"@types/estree@1.0.8", "@types/estree@^1.0.0": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + "@types/events@^3.0.0": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.3.tgz#a8ef894305af28d1fc6d2dfdfc98e899591ea529" @@ -3878,11 +3881,6 @@ resolved "https://registry.yarnpkg.com/@types/pako/-/pako-2.0.3.tgz#b6993334f3af27c158f3fe0dfeeba987c578afb1" integrity sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q== -"@types/parse-json@^4.0.0": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" - integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== - "@types/pbf@*", "@types/pbf@^3.0.5": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/pbf/-/pbf-3.0.5.tgz#a9495a58d8c75be4ffe9a0bd749a307715c07404" @@ -3984,7 +3982,7 @@ resolved "https://registry.yarnpkg.com/@types/seedrandom/-/seedrandom-3.0.8.tgz#61cc8ed88f93a3c31289c295e6df8ca40be42bdf" integrity sha512-TY1eezMU2zH2ozQoAFAQFOPpvP15g+ZgSfTZt31AUUH/Rxtnz3H+A/Sv1Snw2/amp//omibc+AEkTaA8KUeOLQ== -"@types/semver@^7.3.4", "@types/semver@^7.5.8": +"@types/semver@^7.5.8": version "7.7.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.0.tgz#64c441bdae033b378b6eef7d0c3d77c329b9378e" integrity sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA== @@ -4326,7 +4324,7 @@ classnames "^2.5.1" vaul "^1.0.0" -"@vector-im/matrix-wysiwyg-wasm@link:../../bindings/wysiwyg-wasm": +"@vector-im/matrix-wysiwyg-wasm@link:../../Library/Caches/Yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.4-fb0001dea01010a1e3ffc7042596e2d001ce9389-integrity/node_modules/bindings/wysiwyg-wasm": version "0.0.0" uid "" @@ -4335,7 +4333,40 @@ resolved "https://registry.yarnpkg.com/@vector-im/matrix-wysiwyg/-/matrix-wysiwyg-2.38.4.tgz#fb0001dea01010a1e3ffc7042596e2d001ce9389" integrity sha512-X6ky+1cf33SPdEVd6iTmOKfZZ2mDJv9cz3sHtDhuclS6uitK3QE8td/pmGqBj4ek2Ia4y0mnU61LfxvMry1SMA== dependencies: - "@vector-im/matrix-wysiwyg-wasm" "link:../../../.cache/yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.4-fb0001dea01010a1e3ffc7042596e2d001ce9389-integrity/node_modules/bindings/wysiwyg-wasm" + "@vector-im/matrix-wysiwyg-wasm" "link:../../Library/Caches/Yarn/v6/npm-@vector-im-matrix-wysiwyg-2.38.4-fb0001dea01010a1e3ffc7042596e2d001ce9389-integrity/node_modules/bindings/wysiwyg-wasm" + +"@vitest/expect@3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.0.9.tgz#b0cb9cd798a131423097cc5a777b699675405fcf" + integrity sha512-5eCqRItYgIML7NNVgJj6TVCmdzE7ZVgJhruW0ziSQV4V7PvLkDL1bBkBdcTs/VuIz0IxPb5da1IDSqc1TR9eig== + dependencies: + "@vitest/spy" "3.0.9" + "@vitest/utils" "3.0.9" + chai "^5.2.0" + tinyrainbow "^2.0.0" + +"@vitest/pretty-format@3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-3.0.9.tgz#d9c88fe64b4edcdbc88e5bd92c39f9cc8d40930d" + integrity sha512-OW9F8t2J3AwFEwENg3yMyKWweF7oRJlMyHOMIhO5F3n0+cgQAJZBjNgrF8dLwFTEXl5jUqBLXd9QyyKv8zEcmA== + dependencies: + tinyrainbow "^2.0.0" + +"@vitest/spy@3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-3.0.9.tgz#c3e5d47ceff7c1cb9fdfb9b2f168056bbc625534" + integrity sha512-/CcK2UDl0aQ2wtkp3YVWldrpLRNCfVcIOFGlVGKO4R5eajsH393Z1yiXLVQ7vWsj26JOEjeZI0x5sm5P4OGUNQ== + dependencies: + tinyspy "^3.0.2" + +"@vitest/utils@3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-3.0.9.tgz#15da261d8cacd6035dc28a8d3ba38ee39545f82b" + integrity sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng== + dependencies: + "@vitest/pretty-format" "3.0.9" + loupe "^3.1.3" + tinyrainbow "^2.0.0" "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" @@ -4633,7 +4664,7 @@ ansi-escapes@^7.0.0: dependencies: environment "^1.0.0" -ansi-html-community@0.0.8, ansi-html-community@^0.0.8: +ansi-html-community@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== @@ -5433,11 +5464,6 @@ caniuse-lite@1.0.30001724, caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001646, cani resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz#312e163553dd70d2c0fb603d74810c85d8ed94a0" integrity sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA== -case-sensitive-paths-webpack-plugin@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" - integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== - chai@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/chai/-/chai-5.2.0.tgz#1358ee106763624114addf84ab02697e411c9c05" @@ -5541,11 +5567,6 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== -cjs-module-lexer@^1.2.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" - integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== - classnames@^2.2.6, classnames@^2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" @@ -5688,11 +5709,6 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - commonmark@^0.31.0: version "0.31.2" resolved "https://registry.yarnpkg.com/commonmark/-/commonmark-0.31.2.tgz#9d8d5439c82c9a235154d858a53e1a7965d573a5" @@ -5835,17 +5851,6 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - cosmiconfig@^8.1.3: version "8.3.6" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" @@ -5977,20 +5982,6 @@ css-has-pseudo@^7.0.2: postcss-selector-parser "^7.0.0" postcss-value-parser "^4.2.0" -css-loader@^6.7.1: - version "6.11.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" - integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== - dependencies: - icss-utils "^5.1.0" - postcss "^8.4.33" - postcss-modules-extract-imports "^3.1.0" - postcss-modules-local-by-default "^4.0.5" - postcss-modules-scope "^3.2.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.2.0" - semver "^7.5.4" - css-loader@^7.0.0: version "7.1.2" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-7.1.2.tgz#64671541c6efe06b0e22e750503106bdd86880f8" @@ -6277,11 +6268,6 @@ decimal.js@^10.4.3: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.5.0.tgz#0f371c7cf6c4898ce0afb09836db73cd82010f22" integrity sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw== -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - dedent@^1.0.0: version "1.5.3" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" @@ -6664,15 +6650,6 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" -endent@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/endent/-/endent-2.1.0.tgz#5aaba698fb569e5e18e69e1ff7a28ff35373cd88" - integrity sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w== - dependencies: - dedent "^0.7.0" - fast-json-parse "^1.0.3" - objectorarray "^1.0.5" - enhanced-resolve@^5.17.1: version "5.18.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf" @@ -6812,7 +6789,7 @@ es-iterator-helpers@^1.2.1: iterator.prototype "^1.1.4" safe-array-concat "^1.1.3" -es-module-lexer@^1.2.1, es-module-lexer@^1.5.0: +es-module-lexer@^1.2.1: version "1.7.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== @@ -6857,7 +6834,7 @@ esbuild-register@^3.5.0: dependencies: debug "^4.3.4" -"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0": +"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0", esbuild@^0.25.0: version "0.25.5" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.5.tgz#71075054993fdfae76c66586f9b9c1f8d7edd430" integrity sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ== @@ -7210,6 +7187,11 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" @@ -7379,11 +7361,6 @@ fast-glob@^3.2.9, fast-glob@^3.3.2, fast-glob@^3.3.3: merge2 "^1.3.0" micromatch "^4.0.8" -fast-json-parse@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" - integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== - fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -7442,6 +7419,11 @@ fdir@^6.4.3: resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72" integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw== +fdir@^6.4.4, fdir@^6.4.6: + version "6.4.6" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.6.tgz#2b268c0232697063111bbf3f64810a2a741ba281" + integrity sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w== + fetch-mock-jest@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/fetch-mock-jest/-/fetch-mock-jest-1.5.1.tgz#0e13df990d286d9239e284f12b279ed509bf53cd" @@ -7546,15 +7528,6 @@ finalhandler@^2.1.0: parseurl "^1.3.3" statuses "^2.0.1" -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" @@ -7652,24 +7625,6 @@ foreground-child@^3.1.0, foreground-child@^3.3.1: cross-spawn "^7.0.6" signal-exit "^4.0.1" -fork-ts-checker-webpack-plugin@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504" - integrity sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg== - dependencies: - "@babel/code-frame" "^7.16.7" - chalk "^4.1.2" - chokidar "^3.5.3" - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - fs-extra "^10.0.0" - memfs "^3.4.1" - minimatch "^3.0.4" - node-abort-controller "^3.0.1" - schema-utils "^3.1.1" - semver "^7.3.5" - tapable "^2.2.1" - form-data@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.3.tgz#608b1b3f3e28be0fccf5901fc85fb3641e5cf0ae" @@ -7713,15 +7668,6 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs-extra@^9.0.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -7732,11 +7678,6 @@ fs-extra@^9.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-monkey@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" - integrity sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg== - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -7752,7 +7693,7 @@ fsevents@2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fsevents@^2.3.2, fsevents@~2.3.2: +fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -8161,7 +8102,7 @@ html-encoding-sniffer@^3.0.0: dependencies: whatwg-encoding "^2.0.0" -html-entities@^2.0.0, html-entities@^2.1.0: +html-entities@^2.0.0: version "2.6.0" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== @@ -8199,7 +8140,7 @@ html-tags@^3.3.1: resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== -html-webpack-plugin@^5.5.0, html-webpack-plugin@^5.5.3: +html-webpack-plugin@^5.5.3: version "5.6.3" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.3.tgz#a31145f0fee4184d53a794f9513147df1e653685" integrity sha512-QSf1yjtSAsmf7rYBV7XX86uua4W/vkhIt0xNXKbsi2foEeW7vjJQz4bhnpL3xH+l1ryl1680uNv968Z+X6jSYg== @@ -9871,7 +9812,7 @@ magic-string@0.30.8: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -magic-string@^0.30.5: +magic-string@^0.30.0: version "0.30.17" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== @@ -9885,13 +9826,6 @@ mailpit-api@^1.2.0: dependencies: axios "^1.9.0" -make-dir@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - make-dir@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" @@ -10047,13 +9981,6 @@ media-typer@^1.1.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== -memfs@^3.4.1, memfs@^3.4.12: - version "3.6.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== - dependencies: - fs-monkey "^1.0.4" - memfs@^4.6.0: version "4.17.2" resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.17.2.tgz#1f71a6d85c8c53b4f1b388234ed981a690c7e227" @@ -10349,11 +10276,6 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-abort-controller@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" - integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== - node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -10489,11 +10411,6 @@ object.values@^1.2.0: define-properties "^1.2.1" es-object-atoms "^1.0.0" -objectorarray@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" - integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== - obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" @@ -10875,7 +10792,7 @@ pirates@^4.0.4: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== -pkg-dir@^4.1.0, pkg-dir@^4.2.0: +pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== @@ -11546,7 +11463,7 @@ postcss@^8.4.40: picocolors "^1.1.1" source-map-js "^1.2.1" -postcss@^8.5.5: +postcss@^8.5.5, postcss@^8.5.6: version "8.5.6" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== @@ -11858,10 +11775,10 @@ react-docgen-typescript@^2.2.2: resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz#033428b4a6a639d050ac8baf2a5195c596521713" integrity sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg== -react-docgen@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-7.1.1.tgz#a7a8e6b923a945acf0b7325a889ddd74fec74a63" - integrity sha512-hlSJDQ2synMPKFZOsKo9Hi8WWZTC7POR8EmWvTSjow+VDgKzkmjQvFm2fk0tmRw+f0vTOIYKlarR0iL4996pdg== +react-docgen@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-8.0.0.tgz#66b6f750fcba1d1576614ad0ec74204a75fa76c3" + integrity sha512-kmob/FOTwep7DUWf9KjuenKX0vyvChr3oTdvvPt09V60Iz75FJp+T/0ZeHMbAfJj2WaVWqAPP5Hmm3PYzSPPKg== dependencies: "@babel/core" "^7.18.9" "@babel/traverse" "^7.18.9" @@ -12332,6 +12249,35 @@ rimraf@^6.0.0: glob "^11.0.0" package-json-from-dist "^1.0.0" +rollup@^4.40.0: + version "4.44.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.44.1.tgz#641723932894e7acbe6052aea34b8e72ef8b7c8f" + integrity sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg== + dependencies: + "@types/estree" "1.0.8" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.44.1" + "@rollup/rollup-android-arm64" "4.44.1" + "@rollup/rollup-darwin-arm64" "4.44.1" + "@rollup/rollup-darwin-x64" "4.44.1" + "@rollup/rollup-freebsd-arm64" "4.44.1" + "@rollup/rollup-freebsd-x64" "4.44.1" + "@rollup/rollup-linux-arm-gnueabihf" "4.44.1" + "@rollup/rollup-linux-arm-musleabihf" "4.44.1" + "@rollup/rollup-linux-arm64-gnu" "4.44.1" + "@rollup/rollup-linux-arm64-musl" "4.44.1" + "@rollup/rollup-linux-loongarch64-gnu" "4.44.1" + "@rollup/rollup-linux-powerpc64le-gnu" "4.44.1" + "@rollup/rollup-linux-riscv64-gnu" "4.44.1" + "@rollup/rollup-linux-riscv64-musl" "4.44.1" + "@rollup/rollup-linux-s390x-gnu" "4.44.1" + "@rollup/rollup-linux-x64-gnu" "4.44.1" + "@rollup/rollup-linux-x64-musl" "4.44.1" + "@rollup/rollup-win32-arm64-msvc" "4.44.1" + "@rollup/rollup-win32-ia32-msvc" "4.44.1" + "@rollup/rollup-win32-x64-msvc" "4.44.1" + fsevents "~2.3.2" + router@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/router/-/router-2.2.0.tgz#019be620b711c87641167cc79b99090f00b146ef" @@ -12441,7 +12387,7 @@ scheduler@^0.26.0: resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.26.0.tgz#4ce8a8c2a2095f13ea11bf9a445be50c555d6337" integrity sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA== -schema-utils@^3.0.0, schema-utils@^3.1.1: +schema-utils@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== @@ -12488,12 +12434,12 @@ selfsigned@^2.4.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: +semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5, semver@^7.3.7, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2, semver@^7.6.3: +semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.2, semver@^7.6.3: version "7.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== @@ -13122,11 +13068,6 @@ strip-json-comments@^3.1.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -style-loader@^3.3.1: - version "3.3.4" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" - integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== - style-to-js@1.1.16: version "1.1.16" resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.16.tgz#e6bd6cd29e250bcf8fa5e6591d07ced7575dbe7a" @@ -13296,13 +13237,6 @@ svgo@^3.0.2, svgo@^3.3.2: csso "^5.0.5" picocolors "^1.0.0" -swc-loader@^0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/swc-loader/-/swc-loader-0.2.6.tgz#bf0cba8eeff34bb19620ead81d1277fefaec6bc8" - integrity sha512-9Zi9UP2YmDpgmQVbyOPJClY0dwf58JDyDMQ7uRc4krmc72twNI2fvlBWHLqVekBpPc7h5NJkGVT1zNDxFrqhvg== - dependencies: - "@swc/counter" "^0.1.3" - symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -13392,7 +13326,7 @@ temporal-spec@0.3.0: resolved "https://registry.yarnpkg.com/temporal-spec/-/temporal-spec-0.3.0.tgz#8c4210c575fb28ba0a1c2e02ad68d1be5956a11f" integrity sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ== -terser-webpack-plugin@^5.3.1, terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.9: +terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.9: version "5.3.14" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== @@ -13488,6 +13422,14 @@ tinyglobby@^0.2.12: fdir "^6.4.3" picomatch "^4.0.2" +tinyglobby@^0.2.14: + version "0.2.14" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.14.tgz#5280b0cf3f972b050e74ae88406c0a6a58f4079d" + integrity sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ== + dependencies: + fdir "^6.4.4" + picomatch "^4.0.2" + tinyglobby@^0.2.7: version "0.2.9" resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.9.tgz#6baddd1b0fe416403efb0dd40442c7d7c03c1c66" @@ -13999,6 +13941,20 @@ vaul@^1.0.0: dependencies: "@radix-ui/react-dialog" "^1.1.1" +vite@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/vite/-/vite-7.0.1.tgz#b7ebb1e8a7d7f0f42867a545561fb72b34b2b13f" + integrity sha512-BiKOQoW5HGR30E6JDeNsati6HnSPMVEKbkIWbCiol+xKeu3g5owrjy7kbk/QEMuzCV87dSUTvycYKmlcfGKq3Q== + dependencies: + esbuild "^0.25.0" + fdir "^6.4.6" + picomatch "^4.0.2" + postcss "^8.5.6" + rollup "^4.40.0" + tinyglobby "^0.2.14" + optionalDependencies: + fsevents "~2.3.3" + vt-pbf@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac" @@ -14122,17 +14078,6 @@ webpack-cli@^6.0.0: rechoir "^0.8.0" webpack-merge "^6.0.1" -webpack-dev-middleware@^6.1.2: - version "6.1.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz#79f4103f8c898564c9e96c3a9c2422de50f249bc" - integrity sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw== - dependencies: - colorette "^2.0.10" - memfs "^3.4.12" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - webpack-dev-middleware@^7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz#40e265a3d3d26795585cff8207630d3a8ff05877" @@ -14179,15 +14124,6 @@ webpack-dev-server@^5.0.0: webpack-dev-middleware "^7.4.2" ws "^8.18.0" -webpack-hot-middleware@^2.25.1: - version "2.26.1" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz#87214f1e3f9f3acab9271fef9e6ed7b637d719c0" - integrity sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A== - dependencies: - ansi-html-community "0.0.8" - html-entities "^2.1.0" - strip-ansi "^6.0.0" - webpack-merge@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-6.0.1.tgz#50c776868e080574725abc5869bd6e4ef0a16c6a" @@ -14223,12 +14159,12 @@ webpack-virtual-modules@^0.5.0: resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz#362f14738a56dae107937ab98ea7062e8bdd3b6c" integrity sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw== -webpack-virtual-modules@^0.6.0, webpack-virtual-modules@^0.6.2: +webpack-virtual-modules@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8" integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ== -webpack@5, webpack@^5.89.0: +webpack@^5.89.0: version "5.99.9" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.99.9.tgz#d7de799ec17d0cce3c83b70744b4aedb537d8247" integrity sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg== @@ -14504,11 +14440,6 @@ yallist@^3.0.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - yaml@^2.2.2, yaml@^2.3.3, yaml@^2.7.0, yaml@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.0.tgz#15f8c9866211bdc2d3781a0890e44d4fa1a5fff6" From 4fddd23b609bbd713cabe7cea184ce420982c351 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 3 Jul 2025 17:16:21 +0100 Subject: [PATCH 21/30] Change here too --- .storybook/preview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 59806dcb23c..a8dc63d39c8 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,4 +1,4 @@ -import type { ArgTypes, Preview, Decorator } from "@storybook/react-webpack5"; +import type { ArgTypes, Preview, Decorator } from "@storybook/react-vite"; import "../res/css/shared.pcss"; import "./preview.css"; From 703ba8d9fb4a9f48dbc197fc39223bc72b21c57d Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 3 Jul 2025 18:14:09 +0100 Subject: [PATCH 22/30] Workaround for incomatible types in rollup https://github.com/rollup/rollup/issues/5199 --- tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 55e7ae925b5..5f61cb228e2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,8 @@ "lib": ["es2022", "es2024.promise", "dom", "dom.iterable"], "strict": true, "paths": { - "jest-matrix-react": ["./test/test-utils/jest-matrix-react"] + "jest-matrix-react": ["./test/test-utils/jest-matrix-react"], + "rollup/parseAst": ["./node_modules/rollup/dist/parseAst"] } }, "include": [ From de480f6bd5a6a44bfd1eb17931ef2b7d6ce228ad Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 1 Jul 2025 17:27:31 +0200 Subject: [PATCH 23/30] feat: add i18n support to storybook --- .storybook/languageAddon.tsx | 61 ++++ .storybook/main.ts | 20 ++ .storybook/manager.js | 5 + .storybook/preview.tsx | 38 ++- package.json | 2 + src/languageHandler.tsx | 425 ++----------------------- src/shared-components/i18n.tsx | 432 +++++++++++++++++++++++++ yarn.lock | 565 +++++++++++++++++++++++++++++++-- 8 files changed, 1130 insertions(+), 418 deletions(-) create mode 100644 .storybook/languageAddon.tsx create mode 100644 src/shared-components/i18n.tsx diff --git a/.storybook/languageAddon.tsx b/.storybook/languageAddon.tsx new file mode 100644 index 00000000000..0e46e9b25b5 --- /dev/null +++ b/.storybook/languageAddon.tsx @@ -0,0 +1,61 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import { Addon, types, useGlobals } from "storybook/manager-api"; +import { WithTooltip, IconButton, TooltipLinkList } from "storybook/internal/components"; +import React from "react"; +import { GlobeIcon } from "@storybook/icons"; + +// We can't import `shared/i18n.tsx` directly here. +// The storybook addon doesn't seem to benefit the vite config of storybook and we can't resolve the alias in i18n.tsx. +import json from "../webapp/i18n/languages.json"; +const languages = Object.keys(json).filter((lang) => lang !== "default"); + +/** + * Returns the title of a language in the user's locale. + */ +function languageTitle(language: string): string { + return new Intl.DisplayNames([language], { type: "language", style: "short" }).of(language) || language; +} + +export const languageAddon: Addon = { + title: "Language Selector", + type: types.TOOL, + render: ({ active }) => { + const [globals, updateGlobals] = useGlobals(); + const selectedLanguage = globals.language || "en"; + + return ( + { + return ( + ({ + id: language, + title: languageTitle(language), + active: selectedLanguage === language, + onClick: async () => { + // Update the global state with the selected language + updateGlobals({ language }); + onHide(); + }, + }))} + /> + ); + }} + > + + + {languageTitle(selectedLanguage)} + + + ); + }, +}; diff --git a/.storybook/main.ts b/.storybook/main.ts index 95dd14be008..112a5fbb3db 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,7 +1,15 @@ import type { StorybookConfig } from "@storybook/react-vite"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { nodePolyfills } from "vite-plugin-node-polyfills"; +import { mergeConfig } from "vite"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); const config: StorybookConfig = { stories: ["../src/shared-components/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + staticDirs: ["../webapp"], addons: [ "@storybook/addon-docs", "@storybook/addon-designs", @@ -41,5 +49,17 @@ const config: StorybookConfig = { typescript: { reactDocgen: "react-docgen-typescript", }, + async viteFinal(config) { + return mergeConfig(config, { + resolve: { + alias: { + // Alias used by i18n.tsx + $webapp: path.resolve(__dirname, "../webapp"), + }, + }, + // Needed for counterpart to work + plugins: [nodePolyfills({ include: ["process", "util"] })], + }); + }, }; export default config; diff --git a/.storybook/manager.js b/.storybook/manager.js index 97fe237a184..c92bd45b84a 100644 --- a/.storybook/manager.js +++ b/.storybook/manager.js @@ -1,6 +1,11 @@ +import React from "react"; + import { addons } from "storybook/manager-api"; import ElementTheme from "./ElementTheme"; +import { languageAddon } from "./languageAddon"; addons.setConfig({ theme: ElementTheme, }); + +addons.register("elementhq/language", () => addons.add("language", languageAddon)); diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index a8dc63d39c8..8d7516680af 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,13 +1,15 @@ import type { ArgTypes, Preview, Decorator } from "@storybook/react-vite"; +import { addons } from "storybook/preview-api"; import "../res/css/shared.pcss"; import "./preview.css"; import React, { useLayoutEffect } from "react"; +import { FORCE_RE_RENDER } from "storybook/internal/core-events"; +import { setLanguage } from "../src/shared-components/i18n"; export const globalTypes = { theme: { name: "Theme", - defaultValue: "system", description: "Global theme for components", toolbar: { icon: "circlehollow", @@ -21,6 +23,14 @@ export const globalTypes = { ], }, }, + language: { + name: "Language", + description: "Global language for components", + }, + initialGlobals: { + theme: "system", + language: "en", + }, } satisfies ArgTypes; const allThemesClasses = globalTypes.theme.toolbar.items.map(({ value }) => `cpd-theme-${value}`); @@ -48,9 +58,33 @@ const withThemeProvider: Decorator = (Story, context) => { ); }; +const LanguageSwitcher: React.FC<{ + language: string; +}> = ({ language }) => { + useLayoutEffect(() => { + const changeLanguage = async (language: string) => { + await setLanguage(language); + // Force the component to re-render to apply the new language + addons.getChannel().emit(FORCE_RE_RENDER); + }; + changeLanguage(language); + }, [language]); + + return null; +}; + +export const withLanguageProvider: Decorator = (Story, context) => { + return ( + <> + + + + ); +}; + const preview: Preview = { tags: ["autodocs"], - decorators: [withThemeProvider], + decorators: [withThemeProvider, withLanguageProvider], }; export default preview; diff --git a/package.json b/package.json index 695a1819542..3128b644cbc 100644 --- a/package.json +++ b/package.json @@ -192,6 +192,7 @@ "@storybook/addon-designs": "^10.0.1", "@storybook/addon-docs": "^9.0.12", "@storybook/addon-styling-webpack": "^2.0.0", + "@storybook/icons": "^1.4.0", "@storybook/react-vite": "^9.0.15", "@stylistic/eslint-plugin": "^4.0.0", "@svgr/webpack": "^8.0.0", @@ -303,6 +304,7 @@ "typescript": "5.8.3", "util": "^0.12.5", "vite": "^7.0.1", + "vite-plugin-node-polyfills": "^0.24.0", "web-streams-polyfill": "^4.0.0", "webpack": "^5.89.0", "webpack-bundle-analyzer": "^4.8.0", diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx index 175f9c149fb..9ac6cce1c55 100644 --- a/src/languageHandler.tsx +++ b/src/languageHandler.tsx @@ -1,49 +1,49 @@ /* -Copyright 2024 New Vector Ltd. -Copyright 2019-2022 The Matrix.org Foundation C.I.C. -Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> -Copyright 2017 MTRNord and Cooperative EITA -Copyright 2017 Vector Creations Ltd. - -SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial -Please see LICENSE files in the repository root for full details. -*/ + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ import counterpart from "counterpart"; -import React from "react"; import { logger } from "matrix-js-sdk/src/logger"; import { type Optional } from "matrix-events-sdk"; import { MapWithDefault } from "matrix-js-sdk/src/utils"; -import { normalizeLanguageKey, type TranslationKey as _TranslationKey, KEY_SEPARATOR } from "matrix-web-i18n"; import { type TranslationStringsObject } from "@matrix-org/react-sdk-module-api"; import _ from "lodash"; -import type Translations from "./i18n/strings/en_EN.json"; import SettingsStore from "./settings/SettingsStore"; import PlatformPeg from "./PlatformPeg"; import { SettingLevel } from "./settings/SettingLevel"; import { retry } from "./utils/promise"; import SdkConfig from "./SdkConfig"; import { ModuleRunner } from "./modules/ModuleRunner"; - -// @ts-ignore - $webapp is a webpack resolve alias pointing to the output directory, see webpack config -import webpackLangJsonUrl from "$webapp/i18n/languages.json"; - -export { normalizeLanguageKey, getNormalizedLanguageKeys } from "matrix-web-i18n"; +import { + _t, + normalizeLanguageKey, + type TranslationKey, + type IVariables, + KEY_SEPARATOR, + getLangsJson, +} from "./shared-components/i18n"; + +export { + _t, + type IVariables, + type Tags, + type TranslationKey, + type TranslatedString, + _td, + _tDom, + lookupString, + sanitizeForTranslation, + normalizeLanguageKey, + getNormalizedLanguageKeys, + substitute, +} from "./shared-components/i18n"; const i18nFolder = "i18n/"; -// Control whether to also return original, untranslated strings -// Useful for debugging and testing -const ANNOTATE_STRINGS = false; - -// We use english strings as keys, some of which contain full stops -counterpart.setSeparator(KEY_SEPARATOR); - -// see `translateWithFallback` for an explanation of fallback handling -const FALLBACK_LOCALE = "en"; -counterpart.setFallbackLocale(FALLBACK_LOCALE); - export interface ErrorOptions { // Because we're mixing the substitution variables and `cause` into the same object // below, we want them to always explicitly say whether there is an underlying error @@ -96,353 +96,6 @@ export function getUserLanguage(): string { } } -/** - * A type representing the union of possible keys into the translation file using `|` delimiter to access nested fields. - * @example `common|error` to access `error` within the `common` sub-object. - * { - * "common": { - * "error": "Error" - * } - * } - */ -export type TranslationKey = _TranslationKey; - -// Function which only purpose is to mark that a string is translatable -// Does not actually do anything. It's helpful for automatic extraction of translatable strings -export function _td(s: TranslationKey): TranslationKey { - return s; -} - -function isValidTranslation(translated: string): boolean { - return typeof translated === "string" && !translated.startsWith("missing translation:"); -} - -/** - * to improve screen reader experience translations that are not in the main page language - * eg a translation that fell back to english from another language - * should be wrapped with an appropriate `lang='en'` attribute - * counterpart's `translate` doesn't expose a way to determine if the resulting translation - * is in the target locale or a fallback locale - * for this reason, force fallbackLocale === locale in the first call to translate - * and fallback 'manually' so we can mark fallback strings appropriately - * */ -const translateWithFallback = (text: string, options?: IVariables): { translated: string; isFallback?: boolean } => { - const translated = counterpart.translate(text, { ...options, fallbackLocale: counterpart.getLocale() }); - if (isValidTranslation(translated)) { - return { translated }; - } - - const fallbackTranslated = counterpart.translate(text, { ...options, locale: FALLBACK_LOCALE }); - if (isValidTranslation(fallbackTranslated)) { - return { translated: fallbackTranslated, isFallback: true }; - } - - // Even the translation via FALLBACK_LOCALE failed; this can happen if - // - // 1. The string isn't in the translations dictionary, usually because you're in develop - // and haven't run yarn i18n - // 2. Loading the translation resources over the network failed, which can happen due to - // to network or if the client tried to load a translation that's been removed from the - // server. - // - // At this point, its the lesser evil to show the i18n key which will be in English but not human-friendly, - // so the user can still make out *something*, rather than an opaque possibly-untranslated "missing translation" error. - return { translated: text, isFallback: true }; -}; - -// Wrapper for counterpart's translation function so that it handles nulls and undefineds properly -// Takes the same arguments as counterpart.translate() -function safeCounterpartTranslate(text: string, variables?: IVariables): { translated: string; isFallback?: boolean } { - // Don't do substitutions in counterpart. We handle it ourselves so we can replace with React components - // However, still pass the variables to counterpart so that it can choose the correct plural if count is given - // It is enough to pass the count variable, but in the future counterpart might make use of other information too - const options: IVariables & { - interpolate: boolean; - } = { ...variables, interpolate: false }; - - // Horrible hack to avoid https://github.com/vector-im/element-web/issues/4191 - // The interpolation library that counterpart uses does not support undefined/null - // values and instead will throw an error. This is a problem since everywhere else - // in JS land passing undefined/null will simply stringify instead, and when converting - // valid ES6 template strings to i18n strings it's extremely easy to pass undefined/null - // if there are no existing null guards. To avoid this making the app completely inoperable, - // we'll check all the values for undefined/null and stringify them here. - if (options && typeof options === "object") { - Object.keys(options).forEach((k) => { - if (options[k] === undefined) { - logger.warn("safeCounterpartTranslate called with undefined interpolation name: " + k); - options[k] = "undefined"; - } - if (options[k] === null) { - logger.warn("safeCounterpartTranslate called with null interpolation name: " + k); - options[k] = "null"; - } - }); - } - return translateWithFallback(text, options); -} - -/** - * The value a variable or tag can take for a translation interpolation. - */ -type SubstitutionValue = number | string | React.ReactNode | ((sub: string) => React.ReactNode); - -export interface IVariables { - count?: number; - [key: string]: SubstitutionValue; -} - -export type Tags = Record; - -export type TranslatedString = string | React.ReactNode; - -// For development/testing purposes it is useful to also output the original string -// Don't do that for release versions -const annotateStrings = (result: TranslatedString, translationKey: TranslationKey): TranslatedString => { - if (!ANNOTATE_STRINGS) { - return result; - } - - if (typeof result === "string") { - return `@@${translationKey}##${result}@@`; - } else { - return ( - - {result} - - ); - } -}; - -/* - * Translates text and optionally also replaces XML-ish elements in the text with e.g. React components - * @param {string} text The untranslated text, e.g "click here now to %(foo)s". - * @param {object} variables Variable substitutions, e.g { foo: 'bar' } - * @param {object} tags Tag substitutions e.g. { 'a': (sub) => {sub} } - * - * In both variables and tags, the values to substitute with can be either simple strings, React components, - * or functions that return the value to use in the substitution (e.g. return a React component). In case of - * a tag replacement, the function receives as the argument the text inside the element corresponding to the tag. - * - * Use tag substitutions if you need to translate text between tags (e.g. "Click here!"), otherwise - * you will end up with literal "" in your output, rather than HTML. Note that you can also use variable - * substitution to insert React components, but you can't use it to translate text between tags. - * - * @return a React component if any non-strings were used in substitutions, otherwise a string - */ -// eslint-next-line @typescript-eslint/naming-convention -export function _t(text: TranslationKey, variables?: IVariables): string; -export function _t(text: TranslationKey, variables: IVariables | undefined, tags: Tags): React.ReactNode; -export function _t(text: TranslationKey, variables?: IVariables, tags?: Tags): TranslatedString { - // The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution) - const { translated } = safeCounterpartTranslate(text, variables); - const substituted = substitute(translated, variables, tags); - - return annotateStrings(substituted, text); -} - -/** - * Utility function to look up a string by its translation key without resolving variables & tags - * @param key - the translation key to return the value for - */ -export function lookupString(key: TranslationKey): string { - return safeCounterpartTranslate(key, {}).translated; -} - -/* - * Wraps normal _t function and adds atttribution for translations that used a fallback locale - * Wraps translations that fell back from active locale to fallback locale with a `>` - * @param {string} text The untranslated text, e.g "click here now to %(foo)s". - * @param {object} variables Variable substitutions, e.g { foo: 'bar' } - * @param {object} tags Tag substitutions e.g. { 'a': (sub) => {sub} } - * - * @return a React component if any non-strings were used in substitutions - * or translation used a fallback locale, otherwise a string - */ -// eslint-next-line @typescript-eslint/naming-convention -export function _tDom(text: TranslationKey, variables?: IVariables): TranslatedString; -export function _tDom(text: TranslationKey, variables: IVariables, tags: Tags): React.ReactNode; -export function _tDom(text: TranslationKey, variables?: IVariables, tags?: Tags): TranslatedString { - // The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution) - const { translated, isFallback } = safeCounterpartTranslate(text, variables); - const substituted = substitute(translated, variables, tags); - - // wrap en fallback translation with lang attribute for screen readers - const result = isFallback ? {substituted} : substituted; - - return annotateStrings(result, text); -} - -/** - * Sanitizes unsafe text for the sanitizer, ensuring references to variables will not be considered - * replaceable by the translation functions. - * @param {string} text The text to sanitize. - * @returns {string} The sanitized text. - */ -export function sanitizeForTranslation(text: string): string { - // Add a non-breaking space so the regex doesn't trigger when translating. - return text.replace(/%\(([^)]*)\)/g, "%\xa0($1)"); -} - -/* - * Similar to _t(), except only does substitutions, and no translation - * @param {string} text The text, e.g "click here now to %(foo)s". - * @param {object} variables Variable substitutions, e.g { foo: 'bar' } - * @param {object} tags Tag substitutions e.g. { 'a': (sub) => {sub} } - * - * The values to substitute with can be either simple strings, or functions that return the value to use in - * the substitution (e.g. return a React component). In case of a tag replacement, the function receives as - * the argument the text inside the element corresponding to the tag. - * - * @return a React component if any non-strings were used in substitutions, otherwise a string - */ -export function substitute(text: string, variables?: IVariables): string; -export function substitute(text: string, variables: IVariables | undefined, tags: Tags | undefined): string; -export function substitute(text: string, variables?: IVariables, tags?: Tags): string | React.ReactNode { - let result: React.ReactNode | string = text; - - if (variables !== undefined) { - const regexpMapping: IVariables = {}; - for (const variable in variables) { - regexpMapping[`%\\(${variable}\\)s`] = variables[variable]; - } - result = replaceByRegexes(result as string, regexpMapping); - } - - if (tags !== undefined) { - const regexpMapping: Tags = {}; - for (const tag in tags) { - regexpMapping[`(<${tag}>(.*?)<\\/${tag}>|<${tag}>|<${tag}\\s*\\/>)`] = tags[tag]; - } - result = replaceByRegexes(result as string, regexpMapping); - } - - return result; -} - -/** - * Replace parts of a text using regular expressions - * @param text - The text on which to perform substitutions - * @param mapping - A mapping from regular expressions in string form to replacement string or a - * function which will receive as the argument the capture groups defined in the regexp. E.g. - * { 'Hello (.?) World': (sub) => sub.toUpperCase() } - * - * @return a React component if any non-strings were used in substitutions, otherwise a string - */ -export function replaceByRegexes(text: string, mapping: IVariables): string; -export function replaceByRegexes(text: string, mapping: Tags): React.ReactNode; -export function replaceByRegexes(text: string, mapping: IVariables | Tags): string | React.ReactNode { - // We initially store our output as an array of strings and objects (e.g. React components). - // This will then be converted to a string or a at the end - const output: SubstitutionValue[] = [text]; - - // If we insert any components we need to wrap the output in a span. React doesn't like just an array of components. - let shouldWrapInSpan = false; - - for (const regexpString in mapping) { - // TODO: Cache regexps - const regexp = new RegExp(regexpString, "g"); - - // Loop over what output we have so far and perform replacements - // We look for matches: if we find one, we get three parts: everything before the match, the replaced part, - // and everything after the match. Insert all three into the output. We need to do this because we can insert objects. - // Otherwise there would be no need for the splitting and we could do simple replacement. - let matchFoundSomewhere = false; // If we don't find a match anywhere we want to log it - for (let outputIndex = 0; outputIndex < output.length; outputIndex++) { - const inputText = output[outputIndex]; - if (typeof inputText !== "string") { - // We might have inserted objects earlier, don't try to replace them - continue; - } - - // process every match in the string - // starting with the first - let match = regexp.exec(inputText); - - if (!match) continue; - matchFoundSomewhere = true; - - // The textual part before the first match - const head = inputText.slice(0, match.index); - - const parts: SubstitutionValue[] = []; - // keep track of prevMatch - let prevMatch; - while (match) { - // store prevMatch - prevMatch = match; - const capturedGroups = match.slice(2); - - let replaced: SubstitutionValue; - // If substitution is a function, call it - if (mapping[regexpString] instanceof Function) { - replaced = ((mapping as Tags)[regexpString] as (...subs: string[]) => string)(...capturedGroups); - } else { - replaced = mapping[regexpString]; - } - - if (typeof replaced === "object") { - shouldWrapInSpan = true; - } - - // Here we also need to check that it actually is a string before comparing against one - // The head and tail are always strings - if (typeof replaced !== "string" || replaced !== "") { - parts.push(replaced); - } - - // try the next match - match = regexp.exec(inputText); - - // add the text between prevMatch and this one - // or the end of the string if prevMatch is the last match - let tail; - if (match) { - const startIndex = prevMatch.index + prevMatch[0].length; - tail = inputText.slice(startIndex, match.index); - } else { - tail = inputText.slice(prevMatch.index + prevMatch[0].length); - } - if (tail) { - parts.push(tail); - } - } - - // Insert in reverse order as splice does insert-before and this way we get the final order correct - // remove the old element at the same time - output.splice(outputIndex, 1, ...parts); - - if (head !== "") { - // Don't push empty nodes, they are of no use - output.splice(outputIndex, 0, head); - } - } - if (!matchFoundSomewhere) { - if ( - // The current regexp did not match anything in the input. Missing - // matches is entirely possible because you might choose to show some - // variables only in the case of e.g. plurals. It's still a bit - // suspicious, and could be due to an error, so log it. However, not - // showing count is so common that it's not worth logging. And other - // commonly unused variables here, if there are any. - regexpString !== "%\\(count\\)s" && - // Ignore the `locale` option which can be used to override the locale - // in counterpart - regexpString !== "%\\(locale\\)s" - ) { - logger.log(`Could not find ${regexp} in ${text}`); - } - } - } - - if (shouldWrapInSpan) { - return React.createElement("span", null, ...(output as Array)); - } else { - // eslint-disable-next-line @typescript-eslint/no-base-to-string - return output.join(""); - } -} - // Allow overriding the text displayed when no translation exists // Currently only used in unit tests to avoid having to load // the translations in element-web @@ -450,10 +103,6 @@ export function setMissingEntryGenerator(f: (value: string) => void): void { counterpart.setMissingEntryGenerator(f); } -type Languages = { - [lang: string]: string; -}; - export async function setLanguage(...preferredLangs: string[]): Promise { PlatformPeg.get()?.setLanguage(preferredLangs); @@ -554,24 +203,6 @@ export function pickBestLanguage(langs: string[]): string { return langs[0]; } -async function getLangsJson(): Promise { - let url: string; - if (typeof webpackLangJsonUrl === "string") { - // in Jest this 'url' isn't a URL, so just fall through - url = webpackLangJsonUrl; - } else { - url = i18nFolder + "languages.json"; - } - - const res = await fetch(url, { method: "GET" }); - - if (!res.ok) { - throw new Error(`Failed to load ${url}, got ${res.status}`); - } - - return res.json(); -} - interface ICounterpartTranslation { [key: string]: | string diff --git a/src/shared-components/i18n.tsx b/src/shared-components/i18n.tsx new file mode 100644 index 00000000000..e23acff831b --- /dev/null +++ b/src/shared-components/i18n.tsx @@ -0,0 +1,432 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +/* + * Translates text and optionally also replaces XML-ish elements in the text with e.g. React components + * @param {string} text The untranslated text, e.g "click here now to %(foo)s". + * @param {object} variables Variable substitutions, e.g { foo: 'bar' } + * @param {object} tags Tag substitutions e.g. { 'a': (sub) => {sub} } + * + * In both variables and tags, the values to substitute with can be either simple strings, React components, + * or functions that return the value to use in the substitution (e.g. return a React component). In case of + * a tag replacement, the function receives as the argument the text inside the element corresponding to the tag. + * + * Use tag substitutions if you need to translate text between tags (e.g. "Click here!"), otherwise + * you will end up with literal "" in your output, rather than HTML. Note that you can also use variable + * substitution to insert React components, but you can't use it to translate text between tags. + * + * @return a React component if any non-strings were used in substitutions, otherwise a string + */ +import React from "react"; +import { type TranslationKey as _TranslationKey, KEY_SEPARATOR } from "matrix-web-i18n"; +import counterpart from "counterpart"; + +import type Translations from "../i18n/strings/en_EN.json"; + +// @ts-ignore - $webapp is a webpack resolve alias pointing to the output directory, see webpack config +import webpackLangJsonUrl from "$webapp/i18n/languages.json"; + +export { KEY_SEPARATOR, normalizeLanguageKey, getNormalizedLanguageKeys } from "matrix-web-i18n"; + +const i18nFolder = "i18n/"; + +// Control whether to also return original, untranslated strings +// Useful for debugging and testing +const ANNOTATE_STRINGS = false; + +// We use english strings as keys, some of which contain full stops +counterpart.setSeparator(KEY_SEPARATOR); + +// see `translateWithFallback` for an explanation of fallback handling +const FALLBACK_LOCALE = "en"; +counterpart.setFallbackLocale(FALLBACK_LOCALE); + +/** + * A type representing the union of possible keys into the translation file using `|` delimiter to access nested fields. + * @example `common|error` to access `error` within the `common` sub-object. + * { + * "common": { + * "error": "Error" + * } + * } + */ +export type TranslationKey = _TranslationKey; + +// Function which only purpose is to mark that a string is translatable +// Does not actually do anything. It's helpful for automatic extraction of translatable strings +export function _td(s: TranslationKey): TranslationKey { + return s; +} + +function isValidTranslation(translated: string): boolean { + return typeof translated === "string" && !translated.startsWith("missing translation:"); +} + +/** + * to improve screen reader experience translations that are not in the main page language + * eg a translation that fell back to english from another language + * should be wrapped with an appropriate `lang='en'` attribute + * counterpart's `translate` doesn't expose a way to determine if the resulting translation + * is in the target locale or a fallback locale + * for this reason, force fallbackLocale === locale in the first call to translate + * and fallback 'manually' so we can mark fallback strings appropriately + * */ +const translateWithFallback = (text: string, options?: IVariables): { translated: string; isFallback?: boolean } => { + const translated = counterpart.translate(text, { ...options, fallbackLocale: counterpart.getLocale() }); + if (isValidTranslation(translated)) { + return { translated }; + } + + const fallbackTranslated = counterpart.translate(text, { ...options, locale: FALLBACK_LOCALE }); + if (isValidTranslation(fallbackTranslated)) { + return { translated: fallbackTranslated, isFallback: true }; + } + + // Even the translation via FALLBACK_LOCALE failed; this can happen if + // + // 1. The string isn't in the translations dictionary, usually because you're in develop + // and haven't run yarn i18n + // 2. Loading the translation resources over the network failed, which can happen due to + // to network or if the client tried to load a translation that's been removed from the + // server. + // + // At this point, its the lesser evil to show the i18n key which will be in English but not human-friendly, + // so the user can still make out *something*, rather than an opaque possibly-untranslated "missing translation" error. + return { translated: text, isFallback: true }; +}; + +// Wrapper for counterpart's translation function so that it handles nulls and undefineds properly +// Takes the same arguments as counterpart.translate() +function safeCounterpartTranslate(text: string, variables?: IVariables): { translated: string; isFallback?: boolean } { + // Don't do substitutions in counterpart. We handle it ourselves so we can replace with React components + // However, still pass the variables to counterpart so that it can choose the correct plural if count is given + // It is enough to pass the count variable, but in the future counterpart might make use of other information too + const options: IVariables & { + interpolate: boolean; + } = { ...variables, interpolate: false }; + + // Horrible hack to avoid https://github.com/vector-im/element-web/issues/4191 + // The interpolation library that counterpart uses does not support undefined/null + // values and instead will throw an error. This is a problem since everywhere else + // in JS land passing undefined/null will simply stringify instead, and when converting + // valid ES6 template strings to i18n strings it's extremely easy to pass undefined/null + // if there are no existing null guards. To avoid this making the app completely inoperable, + // we'll check all the values for undefined/null and stringify them here. + if (options && typeof options === "object") { + Object.keys(options).forEach((k) => { + if (options[k] === undefined) { + console.warn("safeCounterpartTranslate called with undefined interpolation name: " + k); + options[k] = "undefined"; + } + if (options[k] === null) { + console.warn("safeCounterpartTranslate called with null interpolation name: " + k); + options[k] = "null"; + } + }); + } + return translateWithFallback(text, options); +} + +/** + * The value a variable or tag can take for a translation interpolation. + */ +type SubstitutionValue = number | string | React.ReactNode | ((sub: string) => React.ReactNode); + +export interface IVariables { + count?: number; + [key: string]: SubstitutionValue; +} + +export type Tags = Record; + +export type TranslatedString = string | React.ReactNode; + +// For development/testing purposes it is useful to also output the original string +// Don't do that for release versions +const annotateStrings = (result: TranslatedString, translationKey: TranslationKey): TranslatedString => { + if (!ANNOTATE_STRINGS) { + return result; + } + + if (typeof result === "string") { + return `@@${translationKey}##${result}@@`; + } else { + return ( + + {result} + + ); + } +}; + +export function _t(text: TranslationKey, variables?: IVariables): string; +export function _t(text: TranslationKey, variables: IVariables | undefined, tags: Tags): React.ReactNode; +export function _t(text: TranslationKey, variables?: IVariables, tags?: Tags): TranslatedString { + // The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution) + const { translated } = safeCounterpartTranslate(text, variables); + const substituted = substitute(translated, variables, tags); + + return annotateStrings(substituted, text); +} + +/** + * Utility function to look up a string by its translation key without resolving variables & tags + * @param key - the translation key to return the value for + */ +export function lookupString(key: TranslationKey): string { + return safeCounterpartTranslate(key, {}).translated; +} + +/* + * Wraps normal _t function and adds atttribution for translations that used a fallback locale + * Wraps translations that fell back from active locale to fallback locale with a `>` + * @param {string} text The untranslated text, e.g "click here now to %(foo)s". + * @param {object} variables Variable substitutions, e.g { foo: 'bar' } + * @param {object} tags Tag substitutions e.g. { 'a': (sub) => {sub} } + * + * @return a React component if any non-strings were used in substitutions + * or translation used a fallback locale, otherwise a string + */ +// eslint-next-line @typescript-eslint/naming-convention +export function _tDom(text: TranslationKey, variables?: IVariables): TranslatedString; +export function _tDom(text: TranslationKey, variables: IVariables, tags: Tags): React.ReactNode; +export function _tDom(text: TranslationKey, variables?: IVariables, tags?: Tags): TranslatedString { + // The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution) + const { translated, isFallback } = safeCounterpartTranslate(text, variables); + const substituted = substitute(translated, variables, tags); + + // wrap en fallback translation with lang attribute for screen readers + const result = isFallback ? {substituted} : substituted; + + return annotateStrings(result, text); +} + +/** + * Sanitizes unsafe text for the sanitizer, ensuring references to variables will not be considered + * replaceable by the translation functions. + * @param {string} text The text to sanitize. + * @returns {string} The sanitized text. + */ +export function sanitizeForTranslation(text: string): string { + // Add a non-breaking space so the regex doesn't trigger when translating. + return text.replace(/%\(([^)]*)\)/g, "%\xa0($1)"); +} + +/* + * Similar to _t(), except only does substitutions, and no translation + * @param {string} text The text, e.g "click here now to %(foo)s". + * @param {object} variables Variable substitutions, e.g { foo: 'bar' } + * @param {object} tags Tag substitutions e.g. { 'a': (sub) => {sub} } + * + * The values to substitute with can be either simple strings, or functions that return the value to use in + * the substitution (e.g. return a React component). In case of a tag replacement, the function receives as + * the argument the text inside the element corresponding to the tag. + * + * @return a React component if any non-strings were used in substitutions, otherwise a string + */ +export function substitute(text: string, variables?: IVariables): string; +export function substitute(text: string, variables: IVariables | undefined, tags: Tags | undefined): string; +export function substitute(text: string, variables?: IVariables, tags?: Tags): string | React.ReactNode { + let result: React.ReactNode | string = text; + + if (variables !== undefined) { + const regexpMapping: IVariables = {}; + for (const variable in variables) { + regexpMapping[`%\\(${variable}\\)s`] = variables[variable]; + } + result = replaceByRegexes(result as string, regexpMapping); + } + + if (tags !== undefined) { + const regexpMapping: Tags = {}; + for (const tag in tags) { + regexpMapping[`(<${tag}>(.*?)<\\/${tag}>|<${tag}>|<${tag}\\s*\\/>)`] = tags[tag]; + } + result = replaceByRegexes(result as string, regexpMapping); + } + + return result; +} + +/** + * Replace parts of a text using regular expressions + * @param text - The text on which to perform substitutions + * @param mapping - A mapping from regular expressions in string form to replacement string or a + * function which will receive as the argument the capture groups defined in the regexp. E.g. + * { 'Hello (.?) World': (sub) => sub.toUpperCase() } + * + * @return a React component if any non-strings were used in substitutions, otherwise a string + */ +export function replaceByRegexes(text: string, mapping: IVariables): string; +export function replaceByRegexes(text: string, mapping: Tags): React.ReactNode; +export function replaceByRegexes(text: string, mapping: IVariables | Tags): string | React.ReactNode { + // We initially store our output as an array of strings and objects (e.g. React components). + // This will then be converted to a string or a at the end + const output: SubstitutionValue[] = [text]; + + // If we insert any components we need to wrap the output in a span. React doesn't like just an array of components. + let shouldWrapInSpan = false; + + for (const regexpString in mapping) { + // TODO: Cache regexps + const regexp = new RegExp(regexpString, "g"); + + // Loop over what output we have so far and perform replacements + // We look for matches: if we find one, we get three parts: everything before the match, the replaced part, + // and everything after the match. Insert all three into the output. We need to do this because we can insert objects. + // Otherwise there would be no need for the splitting and we could do simple replacement. + let matchFoundSomewhere = false; // If we don't find a match anywhere we want to log it + for (let outputIndex = 0; outputIndex < output.length; outputIndex++) { + const inputText = output[outputIndex]; + if (typeof inputText !== "string") { + // We might have inserted objects earlier, don't try to replace them + continue; + } + + // process every match in the string + // starting with the first + let match = regexp.exec(inputText); + + if (!match) continue; + matchFoundSomewhere = true; + + // The textual part before the first match + const head = inputText.slice(0, match.index); + + const parts: SubstitutionValue[] = []; + // keep track of prevMatch + let prevMatch; + while (match) { + // store prevMatch + prevMatch = match; + const capturedGroups = match.slice(2); + + let replaced: SubstitutionValue; + // If substitution is a function, call it + if (mapping[regexpString] instanceof Function) { + replaced = ((mapping as Tags)[regexpString] as (...subs: string[]) => string)(...capturedGroups); + } else { + replaced = mapping[regexpString]; + } + + if (typeof replaced === "object") { + shouldWrapInSpan = true; + } + + // Here we also need to check that it actually is a string before comparing against one + // The head and tail are always strings + if (typeof replaced !== "string" || replaced !== "") { + parts.push(replaced); + } + + // try the next match + match = regexp.exec(inputText); + + // add the text between prevMatch and this one + // or the end of the string if prevMatch is the last match + let tail; + if (match) { + const startIndex = prevMatch.index + prevMatch[0].length; + tail = inputText.slice(startIndex, match.index); + } else { + tail = inputText.slice(prevMatch.index + prevMatch[0].length); + } + if (tail) { + parts.push(tail); + } + } + + // Insert in reverse order as splice does insert-before and this way we get the final order correct + // remove the old element at the same time + output.splice(outputIndex, 1, ...parts); + + if (head !== "") { + // Don't push empty nodes, they are of no use + output.splice(outputIndex, 0, head); + } + } + if (!matchFoundSomewhere) { + if ( + // The current regexp did not match anything in the input. Missing + // matches is entirely possible because you might choose to show some + // variables only in the case of e.g. plurals. It's still a bit + // suspicious, and could be due to an error, so log it. However, not + // showing count is so common that it's not worth logging. And other + // commonly unused variables here, if there are any. + regexpString !== "%\\(count\\)s" && + // Ignore the `locale` option which can be used to override the locale + // in counterpart + regexpString !== "%\\(locale\\)s" + ) { + console.log(`Could not find ${regexp} in ${text}`); + } + } + } + + if (shouldWrapInSpan) { + return React.createElement("span", null, ...(output as Array)); + } else { + // eslint-disable-next-line @typescript-eslint/no-base-to-string + return output.join(""); + } +} + +type Languages = { + [lang: string]: string; +}; + +/** + * Sets the language for the application. + * In Element web,`languageHandler.setLanguage` should be used instead. + * @param language + */ +export async function setLanguage(language: string): Promise { + const availableLanguages = await getLangsJson(); + const chosenLanguage = language in availableLanguages ? language : "en"; + + const languageData = await getLanguage(i18nFolder + availableLanguages[chosenLanguage]); + + counterpart.registerTranslations(chosenLanguage, languageData); + counterpart.setLocale(chosenLanguage); +} + +interface ICounterpartTranslation { + [key: string]: + | string + | { + [pluralisation: string]: string; + }; +} + +async function getLanguage(langPath: string): Promise { + console.log("Loading language from", langPath); + const res = await fetch(langPath, { method: "GET" }); + + if (!res.ok) { + throw new Error(`Failed to load ${langPath}, got ${res.status}`); + } + + return res.json(); +} + +export async function getLangsJson(): Promise { + let url: string; + if (typeof webpackLangJsonUrl === "string") { + // in Jest this 'url' isn't a URL, so just fall through + url = webpackLangJsonUrl; + } else { + url = i18nFolder + "languages.json"; + } + + const res = await fetch(url, { method: "GET" }); + + if (!res.ok) { + throw new Error(`Failed to load ${url}, got ${res.status}`); + } + + return res.json(); +} diff --git a/yarn.lock b/yarn.lock index 0a60a526e9b..73e44710323 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2940,7 +2940,16 @@ resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.0.tgz#f817d1d3265ac5415dadc67edab30ae196696438" integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg== -"@rollup/pluginutils@^5.0.2": +"@rollup/plugin-inject@^5.0.5": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz#616f3a73fe075765f91c5bec90176608bed277a3" + integrity sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg== + dependencies: + "@rollup/pluginutils" "^5.0.1" + estree-walker "^2.0.2" + magic-string "^0.30.3" + +"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.0.2": version "5.2.0" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.2.0.tgz#eac25ca5b0bdda4ba735ddaca5fbf26bd435f602" integrity sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw== @@ -3258,7 +3267,7 @@ resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== -"@storybook/icons@^1.2.12": +"@storybook/icons@^1.2.12", "@storybook/icons@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.4.0.tgz#7cf7ab3dfb41943930954c4ef493a73798d8b31d" integrity sha512-Td73IeJxOyalzvjQL+JXx72jlIYHgs+REaHiREOqfpo3A2AYYG71AUbcv+lg7mEDIweKVCxsMQ0UKo634c8XeA== @@ -4891,6 +4900,15 @@ arraybuffer.prototype.slice@^1.0.4: get-intrinsic "^1.2.6" is-array-buffer "^3.0.4" +asn1.js@^4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + asn1@^0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" @@ -4907,6 +4925,17 @@ asn1js@^3.0.5: pvutils "^1.1.3" tslib "^2.4.0" +assert@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" + integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== + dependencies: + call-bind "^1.0.2" + is-nan "^1.3.2" + object-is "^1.1.5" + object.assign "^4.1.4" + util "^0.12.5" + assertion-error@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" @@ -5226,6 +5255,16 @@ blurhash@^2.0.3: resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-2.0.5.tgz#efde729fc14a2f03571a6aa91b49cba80d1abe4b" integrity sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w== +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.2.tgz#3d8fed6796c24e177737f7cc5172ee04ef39ec99" + integrity sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw== + +bn.js@^5.2.1: + version "5.2.2" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.2.tgz#82c09f9ebbb17107cd72cb7fd39bd1f9d0aaa566" + integrity sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw== + body-parser@1.20.3: version "1.20.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" @@ -5294,6 +5333,81 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +browser-resolve@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-2.0.0.tgz#99b7304cb392f8d73dba741bb2d7da28c6d7842b" + integrity sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ== + dependencies: + resolve "^1.17.0" + +browserify-aes@^1.0.4, browserify-aes@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.1.tgz#06e530907fe2949dc21fc3c2e2302e10b1437238" + integrity sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ== + dependencies: + bn.js "^5.2.1" + randombytes "^2.1.0" + safe-buffer "^5.2.1" + +browserify-sign@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.3.tgz#7afe4c01ec7ee59a89a558a4b75bd85ae62d4208" + integrity sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw== + dependencies: + bn.js "^5.2.1" + browserify-rsa "^4.1.0" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.5" + hash-base "~3.0" + inherits "^2.0.4" + parse-asn1 "^5.1.7" + readable-stream "^2.3.8" + safe-buffer "^5.2.1" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + browserslist@^4.0.0, browserslist@^4.23.1, browserslist@^4.23.2, browserslist@^4.23.3, browserslist@^4.24.0, browserslist@^4.24.3, browserslist@^4.25.0: version "4.25.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.0.tgz#986aa9c6d87916885da2b50d8eb577ac8d133b2c" @@ -5328,7 +5442,12 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@^5.5.0: +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer@^5.5.0, buffer@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -5354,6 +5473,11 @@ builtin-modules@^3.3.0: resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== + bundle-name@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889" @@ -5395,7 +5519,7 @@ call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: es-errors "^1.3.0" function-bind "^1.1.2" -call-bind@^1.0.2, call-bind@^1.0.7, call-bind@^1.0.8: +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.7, call-bind@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== @@ -5562,6 +5686,14 @@ ci-info@^4.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.1.0.tgz#92319d2fa29d2620180ea5afed31f589bc98cf83" integrity sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A== +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.6.tgz#8fe672437d01cd6c4561af5334e0cc50ff1955f7" + integrity sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + cjs-module-lexer@^1.0.0: version "1.4.1" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" @@ -5772,6 +5904,16 @@ connect-history-api-fallback@^2.0.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== + content-disposition@0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" @@ -5908,6 +6050,47 @@ crc32-stream@^6.0.0: crc-32 "^1.2.0" readable-stream "^4.0.0" +create-ecdh@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hash@~1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" + integrity sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + ripemd160 "^2.0.0" + sha.js "^2.4.0" + +create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + create-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" @@ -5921,7 +6104,7 @@ create-jest@^29.7.0: jest-util "^29.7.0" prompts "^2.0.1" -create-require@^1.1.0: +create-require@^1.1.0, create-require@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== @@ -5949,6 +6132,24 @@ cross-spawn@^7.0.3, cross-spawn@^7.0.6: shebang-command "^2.0.0" which "^2.0.1" +crypto-browserify@^3.12.1: + version "3.12.1" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.1.tgz#bb8921bec9acc81633379aa8f52d69b0b69e0dac" + integrity sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ== + dependencies: + browserify-cipher "^1.0.1" + browserify-sign "^4.2.3" + create-ecdh "^4.0.4" + create-hash "^1.2.0" + create-hmac "^1.1.7" + diffie-hellman "^5.0.3" + hash-base "~3.0.4" + inherits "^2.0.4" + pbkdf2 "^3.1.2" + public-encrypt "^4.0.3" + randombytes "^2.1.0" + randomfill "^1.0.4" + css-blank-pseudo@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz#32020bff20a209a53ad71b8675852b49e8d57e46" @@ -6349,6 +6550,14 @@ dequal@^2.0.3: resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== +des.js@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -6389,6 +6598,15 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diffie-hellman@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + dijkstrajs@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz#4c8dbdea1f0f6478bff94d9c49c784d623e4fc23" @@ -6495,6 +6713,11 @@ dom-serializer@^2.0.0: domhandler "^5.0.2" entities "^4.2.0" +domain-browser@4.22.0: + version "4.22.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.22.0.tgz#6ddd34220ec281f9a65d3386d267ddd35c491f9f" + integrity sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw== + domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" @@ -6593,6 +6816,19 @@ electron-to-chromium@^1.5.160: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.166.tgz#3fff386ed473cc2169dbe2d3ace9592262601114" integrity sha512-QPWqHL0BglzPYyJJ1zSSmwFFL6MFXhbACOCcsCdUMCkzPdS9/OIBVxg516X/Ado2qwAq8k0nJJ7phQPCqiaFAw== +elliptic@^6.5.3, elliptic@^6.5.5: + version "6.6.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" + integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + emittery@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" @@ -7217,11 +7453,19 @@ eventemitter3@^5.0.1: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== -events@^3.2.0, events@^3.3.0: +events@^3.0.0, events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + except@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/except/-/except-0.1.3.tgz#98261c91958551536b44482238e9783fb73d292a" @@ -8031,6 +8275,38 @@ has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: dependencies: has-symbols "^1.0.3" +hash-base@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-2.0.2.tgz#66ea1d856db4e8a5470cadf6fce23ae5244ef2e1" + integrity sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw== + dependencies: + inherits "^2.0.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash-base@~3.0, hash-base@~3.0.4: + version "3.0.5" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.5.tgz#52480e285395cf7fba17dc4c9e47acdc7f248a8a" + integrity sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + hasown@^2.0.0, hasown@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" @@ -8060,6 +8336,15 @@ highlight.js@^11.3.1: resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.11.1.tgz#fca06fa0e5aeecf6c4d437239135fabc15213585" integrity sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w== +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" @@ -8241,6 +8526,11 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== + https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -8350,7 +8640,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -8601,6 +8891,14 @@ is-map@^2.0.3: resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== +is-nan@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + is-network-error@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-network-error/-/is-network-error-1.1.0.tgz#d26a760e3770226d11c169052f266a4803d9c997" @@ -8773,6 +9071,11 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== +isomorphic-timers-promises@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-timers-promises/-/isomorphic-timers-promises-1.0.1.tgz#e4137c24dbc54892de8abae3a4b5c1ffff381598" + integrity sha512-u4sej9B1LPSxTGKB/HiuzvEQnXH0ECYkSVQU39koSwmFAxhlEAFl9RdTvLv4TOTQUgBS5O3O5fwUxk6byBZ+IQ== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" @@ -9812,7 +10115,7 @@ magic-string@0.30.8: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -magic-string@^0.30.0: +magic-string@^0.30.0, magic-string@^0.30.3: version "0.30.17" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== @@ -9946,6 +10249,15 @@ matrix-widget-api@^1.10.0: "@types/events" "^3.0.0" events "^3.2.0" +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + mdn-data@2.0.28: version "2.0.28" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" @@ -10039,6 +10351,14 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -10096,11 +10416,16 @@ mini-css-extract-plugin@2.9.2: schema-utils "^4.0.0" tapable "^2.2.1" -minimalistic-assert@^1.0.0: +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + minimatch@^10.0.0: version "10.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" @@ -10298,6 +10623,39 @@ node-releases@^2.0.19: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314" integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw== +node-stdlib-browser@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-stdlib-browser/-/node-stdlib-browser-1.3.1.tgz#f41fa554f720a3df951e40339f4d92ac512222ac" + integrity sha512-X75ZN8DCLftGM5iKwoYLA3rjnrAEs97MkzvSd4q2746Tgpg8b8XWiBGiBG4ZpgcAqBgtgPHTiAc8ZMCvZuikDw== + dependencies: + assert "^2.0.0" + browser-resolve "^2.0.0" + browserify-zlib "^0.2.0" + buffer "^5.7.1" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + create-require "^1.1.1" + crypto-browserify "^3.12.1" + domain-browser "4.22.0" + events "^3.0.0" + https-browserify "^1.0.0" + isomorphic-timers-promises "^1.0.1" + os-browserify "^0.3.0" + path-browserify "^1.0.1" + pkg-dir "^5.0.0" + process "^0.11.10" + punycode "^1.4.1" + querystring-es3 "^0.2.1" + readable-stream "^3.6.0" + stream-browserify "^3.0.0" + stream-http "^3.2.0" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.1" + url "^0.11.4" + util "^0.12.4" + vm-browserify "^1.0.1" + normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -10347,6 +10705,14 @@ object-inspect@^1.13.3: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== +object-is@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" + integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -10505,6 +10871,11 @@ opus-recorder@^8.0.3: resolved "https://registry.yarnpkg.com/opus-recorder/-/opus-recorder-8.0.5.tgz#06d3e32e15da57ebc3f57e41b93033475fcb4e3e" integrity sha512-tBRXc9Btds7i3bVfA7d5rekAlyOcfsivt5vSIXHxRV1Oa+s6iXFW8omZ0Lm3ABWotVcEyKt96iIIUcgbV07YOw== +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -10612,7 +10983,7 @@ pako@^2.0.3: resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== -pako@~1.0.2: +pako@~1.0.2, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -10632,6 +11003,18 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-asn1@^5.0.0, parse-asn1@^5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.7.tgz#73cdaaa822125f9647165625eb45f8a051d2df06" + integrity sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg== + dependencies: + asn1.js "^4.10.1" + browserify-aes "^1.2.0" + evp_bytestokey "^1.0.3" + hash-base "~3.0" + pbkdf2 "^3.1.2" + safe-buffer "^5.2.1" + parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -10688,6 +11071,11 @@ patch-package@^8.0.0: tmp "^0.0.33" yaml "^2.2.2" +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -10762,6 +11150,18 @@ pbf@^3.2.1, pbf@^3.3.0: ieee754 "^1.1.12" resolve-protobuf-schema "^2.1.0" +pbkdf2@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.3.tgz#8be674d591d65658113424592a95d1517318dd4b" + integrity sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA== + dependencies: + create-hash "~1.1.3" + create-hmac "^1.1.7" + ripemd160 "=2.0.1" + safe-buffer "^5.2.1" + sha.js "^2.4.11" + to-buffer "^1.2.0" + picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0, picocolors@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" @@ -10799,6 +11199,13 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + playwright-core@1.53.1, playwright-core@^1.51.0: version "1.53.1" resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.53.1.tgz#0b6f7a2006ccb6126ffcc3e3b2fa9efda23b6638" @@ -11622,6 +12029,18 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +public-encrypt@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + pump@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8" @@ -11630,6 +12049,11 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + punycode@^2.1.0, punycode@^2.1.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -11668,13 +12092,18 @@ qs@6.13.0: dependencies: side-channel "^1.0.6" -qs@^6.14.0: +qs@^6.12.3, qs@^6.14.0: version "6.14.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930" integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w== dependencies: side-channel "^1.1.0" +querystring-es3@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== + querystring@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" @@ -11700,13 +12129,21 @@ raf-schd@^4.0.2: resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a" integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ== -randombytes@^2.1.0: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" +randomfill@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -11933,7 +12370,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -readable-stream@^2.0.1, readable-stream@^2.0.5, readable-stream@~2.3.6: +readable-stream@^2.0.1, readable-stream@^2.0.5, readable-stream@^2.3.8, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -11946,7 +12383,7 @@ readable-stream@^2.0.1, readable-stream@^2.0.5, readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0: +readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -12176,7 +12613,7 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.4, resolve@^1.22 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.14.2, resolve@^1.22.1: +resolve@^1.14.2, resolve@^1.17.0, resolve@^1.22.1: version "1.22.10" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== @@ -12249,6 +12686,22 @@ rimraf@^6.0.0: glob "^11.0.0" package-json-from-dist "^1.0.0" +ripemd160@=2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.1.tgz#0f4584295c53a3628af7e6d79aca21ce57d1c6e7" + integrity sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w== + dependencies: + hash-base "^2.0.0" + inherits "^2.0.1" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + rollup@^4.40.0: version "4.44.1" resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.44.1.tgz#641723932894e7acbe6052aea34b8e72ef8b7c8f" @@ -12324,7 +12777,7 @@ safe-array-concat@^1.1.3: has-symbols "^1.1.0" isarray "^2.0.5" -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -12556,7 +13009,7 @@ set-proto@^1.0.0: es-errors "^1.3.0" es-object-atoms "^1.0.0" -setimmediate@^1.0.5: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== @@ -12571,6 +13024,15 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8: + version "2.4.12" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f" + integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w== + dependencies: + inherits "^2.0.4" + safe-buffer "^5.2.1" + to-buffer "^1.2.0" + shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -12867,6 +13329,24 @@ storybook@^9.0.12: semver "^7.6.2" ws "^8.18.0" +stream-browserify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + +stream-http@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5" + integrity sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.4" + readable-stream "^3.6.0" + xtend "^4.0.2" + streamx@^2.15.0, streamx@^2.21.0: version "2.22.1" resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.22.1.tgz#c97cbb0ce18da4f4db5a971dc9ab68ff5dc7f5a5" @@ -12994,7 +13474,7 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" -string_decoder@^1.1.1, string_decoder@^1.3.0: +string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -13409,6 +13889,13 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== +timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + tiny-invariant@^1.0.6, tiny-invariant@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" @@ -13470,6 +13957,15 @@ tmpl@1.0.5: resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== +to-buffer@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.1.tgz#2ce650cdb262e9112a18e65dc29dcb513c8155e0" + integrity sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ== + dependencies: + isarray "^2.0.5" + safe-buffer "^5.2.1" + typed-array-buffer "^1.0.3" + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -13596,6 +14092,11 @@ tslib@^2.6.1, tslib@^2.6.2, tslib@^2.7.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b" integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA== +tty-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== + tweetnacl@^0.14.3: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -13829,6 +14330,14 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" +url@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.4.tgz#adca77b3562d56b72746e76b330b7f27b6721f3c" + integrity sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg== + dependencies: + punycode "^1.4.1" + qs "^6.12.3" + use-callback-ref@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693" @@ -13866,7 +14375,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util@^0.12.5: +util@^0.12.4, util@^0.12.5: version "0.12.5" resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -13941,6 +14450,14 @@ vaul@^1.0.0: dependencies: "@radix-ui/react-dialog" "^1.1.1" +vite-plugin-node-polyfills@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.24.0.tgz#4a2e984bba134017fc88cace0149cf8afdb50b54" + integrity sha512-GA9QKLH+vIM8NPaGA+o2t8PDfFUl32J8rUp1zQfMKVJQiNkOX4unE51tR6ppl6iKw5yOrDAdSH7r/UIFLCVhLw== + dependencies: + "@rollup/plugin-inject" "^5.0.5" + node-stdlib-browser "^1.2.0" + vite@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/vite/-/vite-7.0.1.tgz#b7ebb1e8a7d7f0f42867a545561fb72b34b2b13f" @@ -13955,6 +14472,11 @@ vite@^7.0.1: optionalDependencies: fsevents "~2.3.3" +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + vt-pbf@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-3.1.3.tgz#68fd150756465e2edae1cc5c048e063916dcfaac" @@ -14418,6 +14940,11 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +xtend@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + xxhashjs@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/xxhashjs/-/xxhashjs-0.2.2.tgz#8a6251567621a1c46a5ae204da0249c7f8caa9d8" From a9cff10ed65a61b8746a1d83bcb77ad19bf20c21 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Mon, 7 Jul 2025 17:03:56 +0200 Subject: [PATCH 24/30] fix: make webpack build works again --- src/accessibility/KeyboardShortcuts.ts | 3 ++- src/settings/Settings.tsx | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/accessibility/KeyboardShortcuts.ts b/src/accessibility/KeyboardShortcuts.ts index ec5b8312b92..fd820206325 100644 --- a/src/accessibility/KeyboardShortcuts.ts +++ b/src/accessibility/KeyboardShortcuts.ts @@ -8,7 +8,8 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { _td, type TranslationKey } from "../languageHandler"; +// We need to import directly from the shared i18n instead of the language handler due to a webpack loading error +import { _td, type TranslationKey } from "../shared-components/i18n"; import { IS_MAC, IS_ELECTRON, Key } from "../Keyboard"; import { type IBaseSetting } from "../settings/Settings"; import { type KeyCombo } from "../KeyBindingsManager"; diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index 1140d24ed8e..d99afd90706 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -11,7 +11,8 @@ import React, { type ReactNode } from "react"; import { UNSTABLE_MSC4133_EXTENDED_PROFILES } from "matrix-js-sdk/src/matrix"; import { type MediaPreviewConfig } from "../@types/media_preview.ts"; -import { _t, _td, type TranslationKey } from "../languageHandler"; +// We need to import directly from the shared i18n instead of the language handler due to a webpack loading error +import { _t, _td, type TranslationKey } from "../shared-components/i18n"; import DeviceIsolationModeController from "./controllers/DeviceIsolationModeController.ts"; import { NotificationBodyEnabledController, From c86b12883a613975b7d80a10f7397fc1ba281f90 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 8 Jul 2025 16:07:17 +0200 Subject: [PATCH 25/30] refactor: move Flex component into shared-components folder --- src/async-components/structures/ErrorView.tsx | 2 +- .../security/AccessSecretStorageDialog.tsx | 2 +- src/components/views/right_panel/EmptyState.tsx | 2 +- .../views/right_panel/RoomSummaryCardView.tsx | 2 +- src/components/views/right_panel/UserInfo.tsx | 2 +- .../rooms/MemberList/MemberListHeaderView.tsx | 2 +- .../views/rooms/MemberList/MemberListView.tsx | 2 +- .../MemberList/tiles/common/InvitedIconView.tsx | 2 +- .../views/rooms/NotificationDecoration.tsx | 2 +- .../views/rooms/RoomHeader/RoomHeader.tsx | 2 +- .../views/rooms/RoomListPanel/EmptyRoomList.tsx | 2 +- .../rooms/RoomListPanel/RoomListHeaderView.tsx | 2 +- .../rooms/RoomListPanel/RoomListItemMenuView.tsx | 2 +- .../rooms/RoomListPanel/RoomListItemView.tsx | 2 +- .../views/rooms/RoomListPanel/RoomListPanel.tsx | 2 +- .../RoomListPanel/RoomListPrimaryFilters.tsx | 2 +- .../views/rooms/RoomListPanel/RoomListSearch.tsx | 2 +- .../views/rooms/ThirdPartyMemberInfo.tsx | 2 +- .../views/settings/UserProfileSettings.tsx | 2 +- .../EncryptionCardEmphasisedContent.tsx | 2 +- src/shared-components/Flex/Flex.module.css | 15 +++++++++++++++ .../utils => shared-components/Flex}/Flex.tsx | 15 ++++++++------- src/shared-components/Flex/index.ts | 8 ++++++++ 23 files changed, 51 insertions(+), 27 deletions(-) create mode 100644 src/shared-components/Flex/Flex.module.css rename src/{components/utils => shared-components/Flex}/Flex.tsx (87%) create mode 100644 src/shared-components/Flex/index.ts diff --git a/src/async-components/structures/ErrorView.tsx b/src/async-components/structures/ErrorView.tsx index 0f9a61781ed..191fa61c5ca 100644 --- a/src/async-components/structures/ErrorView.tsx +++ b/src/async-components/structures/ErrorView.tsx @@ -10,7 +10,7 @@ import { Text, Heading, Button, Separator } from "@vector-im/compound-web"; import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out"; import SdkConfig from "../../SdkConfig"; -import { Flex } from "../../components/utils/Flex"; +import { Flex } from "../../shared-components/Flex"; import { _t } from "../../languageHandler"; import { Icon as AppleIcon } from "../../../res/themes/element/img/compound/apple.svg"; import { Icon as MicrosoftIcon } from "../../../res/themes/element/img/compound/microsoft.svg"; diff --git a/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx b/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx index 10f4788580e..b77ee8ab3b4 100644 --- a/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx +++ b/src/components/views/dialogs/security/AccessSecretStorageDialog.tsx @@ -14,7 +14,7 @@ import React, { type ChangeEvent, type FormEvent } from "react"; import { type SecretStorage } from "matrix-js-sdk/src/matrix"; import Field from "../../elements/Field"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { _t } from "../../../../languageHandler"; import { EncryptionCard } from "../../settings/encryption/EncryptionCard"; import { EncryptionCardButtons } from "../../settings/encryption/EncryptionCardButtons"; diff --git a/src/components/views/right_panel/EmptyState.tsx b/src/components/views/right_panel/EmptyState.tsx index f6b2a940a63..567a5e1dea7 100644 --- a/src/components/views/right_panel/EmptyState.tsx +++ b/src/components/views/right_panel/EmptyState.tsx @@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details. import React, { type ComponentType } from "react"; import { Text } from "@vector-im/compound-web"; -import { Flex } from "../../utils/Flex"; +import { Flex } from "../../../shared-components/Flex"; interface Props { Icon: ComponentType>; diff --git a/src/components/views/right_panel/RoomSummaryCardView.tsx b/src/components/views/right_panel/RoomSummaryCardView.tsx index d994e697c6e..76fcb596e92 100644 --- a/src/components/views/right_panel/RoomSummaryCardView.tsx +++ b/src/components/views/right_panel/RoomSummaryCardView.tsx @@ -46,7 +46,7 @@ import RoomAvatar from "../avatars/RoomAvatar.tsx"; import { E2EStatus } from "../../../utils/ShieldUtils.ts"; import { type RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks.ts"; import RoomName from "../elements/RoomName.tsx"; -import { Flex } from "../../utils/Flex.tsx"; +import { Flex } from "../../../shared-components/Flex"; import { Linkify, topicToHtml } from "../../../HtmlUtils.tsx"; import { Box } from "../../utils/Box.tsx"; import { ReleaseAnnouncement } from "../../structures/ReleaseAnnouncement.tsx"; diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index 970f8a22786..4681b132404 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -70,7 +70,7 @@ import PosthogTrackers from "../../../PosthogTrackers"; import { type ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; import { DirectoryMember, startDmOnFirstMessage } from "../../../utils/direct-messages"; import { SdkContextClass } from "../../../contexts/SDKContext"; -import { Flex } from "../../utils/Flex"; +import { Flex } from "../../../shared-components/Flex"; import CopyableText from "../elements/CopyableText"; import { useUserTimezone } from "../../../hooks/useUserTimezone"; import { UserInfoAdminToolsContainer } from "./user_info/UserInfoAdminToolsContainer"; diff --git a/src/components/views/rooms/MemberList/MemberListHeaderView.tsx b/src/components/views/rooms/MemberList/MemberListHeaderView.tsx index 88fc07881c8..31bcfb29f26 100644 --- a/src/components/views/rooms/MemberList/MemberListHeaderView.tsx +++ b/src/components/views/rooms/MemberList/MemberListHeaderView.tsx @@ -10,7 +10,7 @@ import React from "react"; import InviteIcon from "@vector-im/compound-design-tokens/assets/web/icons/user-add-solid"; import { UserAddIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { type MemberListViewState } from "../../../viewmodels/memberlist/MemberListViewModel"; import { _t } from "../../../../languageHandler"; diff --git a/src/components/views/rooms/MemberList/MemberListView.tsx b/src/components/views/rooms/MemberList/MemberListView.tsx index 0b5629685c9..269201972b4 100644 --- a/src/components/views/rooms/MemberList/MemberListView.tsx +++ b/src/components/views/rooms/MemberList/MemberListView.tsx @@ -10,7 +10,7 @@ import React, { type JSX } from "react"; import { List, type ListRowProps } from "react-virtualized/dist/commonjs/List"; import { AutoSizer } from "react-virtualized"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { type MemberWithSeparator, SEPARATOR, diff --git a/src/components/views/rooms/MemberList/tiles/common/InvitedIconView.tsx b/src/components/views/rooms/MemberList/tiles/common/InvitedIconView.tsx index 8a7f0e06a46..f5bb51ab711 100644 --- a/src/components/views/rooms/MemberList/tiles/common/InvitedIconView.tsx +++ b/src/components/views/rooms/MemberList/tiles/common/InvitedIconView.tsx @@ -9,7 +9,7 @@ import React, { type JSX } from "react"; import EmailIcon from "@vector-im/compound-design-tokens/assets/web/icons/email-solid"; import UserAddIcon from "@vector-im/compound-design-tokens/assets/web/icons/user-add-solid"; -import { Flex } from "../../../../../utils/Flex"; +import { Flex } from "../../../../../../shared-components/Flex"; interface Props { isThreePid: boolean; diff --git a/src/components/views/rooms/NotificationDecoration.tsx b/src/components/views/rooms/NotificationDecoration.tsx index a93f1428fd9..5f5b3d45737 100644 --- a/src/components/views/rooms/NotificationDecoration.tsx +++ b/src/components/views/rooms/NotificationDecoration.tsx @@ -13,7 +13,7 @@ import VideoCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/vi import EmailIcon from "@vector-im/compound-design-tokens/assets/web/icons/email-solid"; import { UnreadCounter, Unread } from "@vector-im/compound-web"; -import { Flex } from "../../utils/Flex"; +import { Flex } from "../../../shared-components/Flex"; import { type RoomNotificationState } from "../../../stores/notifications/RoomNotificationState"; import { useTypedEventEmitterState } from "../../../hooks/useEventEmitter"; import { NotificationStateEvents } from "../../../stores/notifications/NotificationState"; diff --git a/src/components/views/rooms/RoomHeader/RoomHeader.tsx b/src/components/views/rooms/RoomHeader/RoomHeader.tsx index 663c8e9ff0c..2ff51d3765b 100644 --- a/src/components/views/rooms/RoomHeader/RoomHeader.tsx +++ b/src/components/views/rooms/RoomHeader/RoomHeader.tsx @@ -25,7 +25,7 @@ import { RightPanelPhases } from "../../../../stores/right-panel/RightPanelStore import { useMatrixClientContext } from "../../../../contexts/MatrixClientContext.tsx"; import { useRoomMemberCount, useRoomMembers } from "../../../../hooks/useRoomMembers.ts"; import { _t } from "../../../../languageHandler.tsx"; -import { Flex } from "../../../utils/Flex.tsx"; +import { Flex } from "../../../../shared-components/Flex"; import { Box } from "../../../utils/Box.tsx"; import { getPlatformCallTypeProps, useRoomCall } from "../../../../hooks/room/useRoomCall.tsx"; import { useRoomThreadNotifications } from "../../../../hooks/room/useRoomThreadNotifications.ts"; diff --git a/src/components/views/rooms/RoomListPanel/EmptyRoomList.tsx b/src/components/views/rooms/RoomListPanel/EmptyRoomList.tsx index 0e3412f5888..f626c57e70c 100644 --- a/src/components/views/rooms/RoomListPanel/EmptyRoomList.tsx +++ b/src/components/views/rooms/RoomListPanel/EmptyRoomList.tsx @@ -11,7 +11,7 @@ import UserAddIcon from "@vector-im/compound-design-tokens/assets/web/icons/user import RoomIcon from "@vector-im/compound-design-tokens/assets/web/icons/room"; import type { RoomListViewState } from "../../../viewmodels/roomlist/RoomListViewModel"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { _t } from "../../../../languageHandler"; import { FilterKey } from "../../../../stores/room-list-v3/skip-list/filters"; import { type PrimaryFilter } from "../../../viewmodels/roomlist/useFilteredRooms"; diff --git a/src/components/views/rooms/RoomListPanel/RoomListHeaderView.tsx b/src/components/views/rooms/RoomListPanel/RoomListHeaderView.tsx index 752f065fd4b..02a7ccc6305 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListHeaderView.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListHeaderView.tsx @@ -16,7 +16,7 @@ import SettingsIcon from "@vector-im/compound-design-tokens/assets/web/icons/set import VideoCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/video-call"; import { _t } from "../../../../languageHandler"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { type RoomListHeaderViewState, useRoomListHeaderViewModel, diff --git a/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx b/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx index a901003342d..cd9dad6469e 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx @@ -21,7 +21,7 @@ import CheckIcon from "@vector-im/compound-design-tokens/assets/web/icons/check" import { type Room } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../../languageHandler"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { type RoomListItemMenuViewState, useRoomListItemMenuViewModel, diff --git a/src/components/views/rooms/RoomListPanel/RoomListItemView.tsx b/src/components/views/rooms/RoomListPanel/RoomListItemView.tsx index cabb034975a..5e246af2148 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListItemView.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListItemView.tsx @@ -10,7 +10,7 @@ import { type Room } from "matrix-js-sdk/src/matrix"; import classNames from "classnames"; import { useRoomListItemViewModel } from "../../../viewmodels/roomlist/RoomListItemViewModel"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { RoomListItemMenuView } from "./RoomListItemMenuView"; import { NotificationDecoration } from "../NotificationDecoration"; import { RoomAvatarView } from "../../avatars/RoomAvatarView"; diff --git a/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx b/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx index f5c0620a663..b09636cddf2 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx @@ -12,7 +12,7 @@ import { UIComponent } from "../../../../settings/UIFeature"; import { RoomListSearch } from "./RoomListSearch"; import { RoomListHeaderView } from "./RoomListHeaderView"; import { RoomListView } from "./RoomListView"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { _t } from "../../../../languageHandler"; type RoomListPanelProps = { diff --git a/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx b/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx index 676501a3ea0..e8f2831f2b3 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx @@ -10,7 +10,7 @@ import { ChatFilter, IconButton } from "@vector-im/compound-web"; import ChevronDownIcon from "@vector-im/compound-design-tokens/assets/web/icons/chevron-down"; import type { RoomListViewState } from "../../../viewmodels/roomlist/RoomListViewModel"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { _t } from "../../../../languageHandler"; interface RoomListPrimaryFiltersProps { diff --git a/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx b/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx index 26f0ff8baed..aececc300da 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx @@ -20,7 +20,7 @@ import { MetaSpace } from "../../../../stores/spaces"; import { Action } from "../../../../dispatcher/actions"; import PosthogTrackers from "../../../../PosthogTrackers"; import defaultDispatcher from "../../../../dispatcher/dispatcher"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; import { useTypedEventEmitterState } from "../../../../hooks/useEventEmitter"; import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../../../LegacyCallHandler"; diff --git a/src/components/views/rooms/ThirdPartyMemberInfo.tsx b/src/components/views/rooms/ThirdPartyMemberInfo.tsx index da626992a18..788891000f7 100644 --- a/src/components/views/rooms/ThirdPartyMemberInfo.tsx +++ b/src/components/views/rooms/ThirdPartyMemberInfo.tsx @@ -19,7 +19,7 @@ import { isValid3pidInvite } from "../../../RoomInvite"; import { Action } from "../../../dispatcher/actions"; import ErrorDialog from "../dialogs/ErrorDialog"; import BaseCard from "../right_panel/BaseCard"; -import { Flex } from "../../utils/Flex"; +import { Flex } from "../../../shared-components/Flex"; interface IProps { event: MatrixEvent; diff --git a/src/components/views/settings/UserProfileSettings.tsx b/src/components/views/settings/UserProfileSettings.tsx index 11b6a5bb69a..6a904257395 100644 --- a/src/components/views/settings/UserProfileSettings.tsx +++ b/src/components/views/settings/UserProfileSettings.tsx @@ -26,7 +26,7 @@ import AccessibleButton from "../elements/AccessibleButton"; import LogoutDialog, { shouldShowLogoutDialog } from "../dialogs/LogoutDialog"; import Modal from "../../../Modal"; import defaultDispatcher from "../../../dispatcher/dispatcher"; -import { Flex } from "../../utils/Flex"; +import { Flex } from "../../../shared-components/Flex"; const SpinnerToast: React.FC<{ children?: ReactNode }> = ({ children }) => ( <> diff --git a/src/components/views/settings/encryption/EncryptionCardEmphasisedContent.tsx b/src/components/views/settings/encryption/EncryptionCardEmphasisedContent.tsx index e630ebaa9fa..b50e06266c2 100644 --- a/src/components/views/settings/encryption/EncryptionCardEmphasisedContent.tsx +++ b/src/components/views/settings/encryption/EncryptionCardEmphasisedContent.tsx @@ -7,7 +7,7 @@ import React, { type JSX, type PropsWithChildren } from "react"; -import { Flex } from "../../../utils/Flex"; +import { Flex } from "../../../../shared-components/Flex"; /** * A component for emphasised text within an {@link EncryptionCard} diff --git a/src/shared-components/Flex/Flex.module.css b/src/shared-components/Flex/Flex.module.css new file mode 100644 index 00000000000..9889d6ed101 --- /dev/null +++ b/src/shared-components/Flex/Flex.module.css @@ -0,0 +1,15 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +.flex { + display: var(--mx-flex-display, unset); + flex-direction: var(--mx-flex-direction, unset); + align-items: var(--mx-flex-align, unset); + justify-content: var(--mx-flex-justify, unset); + gap: var(--mx-flex-gap, unset); + flex-wrap: var(--mx-flex-wrap, unset); +} diff --git a/src/components/utils/Flex.tsx b/src/shared-components/Flex/Flex.tsx similarity index 87% rename from src/components/utils/Flex.tsx rename to src/shared-components/Flex/Flex.tsx index 0a8c3c2fa4f..deb5b8a8179 100644 --- a/src/components/utils/Flex.tsx +++ b/src/shared-components/Flex/Flex.tsx @@ -1,14 +1,15 @@ /* -Copyright 2024 New Vector Ltd. -Copyright 2023 The Matrix.org Foundation C.I.C. - -SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial -Please see LICENSE files in the repository root for full details. -*/ + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ import classNames from "classnames"; import React, { type JSX, type ComponentProps, type JSXElementConstructor, useMemo } from "react"; +import styles from "./Flex.module.css"; + type FlexProps> = { /** * The type of the HTML element @@ -82,5 +83,5 @@ export function Flex Date: Tue, 8 Jul 2025 11:40:05 +0200 Subject: [PATCH 26/30] refactor: move Keyboard.ts into shared-components folder --- src/KeyBindingsDefaults.ts | 2 +- src/KeyBindingsManager.ts | 2 +- src/accessibility/KeyboardShortcutUtils.ts | 2 +- src/accessibility/KeyboardShortcuts.ts | 2 +- src/components/structures/AutocompleteInput.tsx | 2 +- src/components/structures/LoggedInView.tsx | 2 +- src/components/structures/RoomSearch.tsx | 2 +- .../viewmodels/right_panel/RoomSummaryCardViewModel.tsx | 2 +- src/components/views/emojipicker/EmojiPicker.tsx | 2 +- src/components/views/messages/MessageActionBar.tsx | 2 +- src/components/views/rooms/BasicMessageComposer.tsx | 2 +- src/components/views/rooms/RoomListPanel/RoomListSearch.tsx | 2 +- .../views/rooms/wysiwyg_composer/hooks/usePlainTextListeners.ts | 2 +- src/components/views/settings/KeyboardShortcut.tsx | 2 +- .../views/settings/tabs/user/PreferencesUserSettingsTab.tsx | 2 +- src/settings/Settings.tsx | 2 +- src/{ => shared-components}/Keyboard.ts | 0 .../components/views/elements/AccessibleButton-test.tsx | 2 +- .../wysiwyg_composer/components/PlainTextComposer-test.tsx | 2 +- .../components/views/settings/KeyboardShortcut-test.tsx | 2 +- .../views/settings/tabs/user/KeyboardUserSettingsTab-test.tsx | 2 +- 21 files changed, 20 insertions(+), 20 deletions(-) rename src/{ => shared-components}/Keyboard.ts (100%) diff --git a/src/KeyBindingsDefaults.ts b/src/KeyBindingsDefaults.ts index 0ab6acf030c..3ff9295c525 100644 --- a/src/KeyBindingsDefaults.ts +++ b/src/KeyBindingsDefaults.ts @@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com Please see LICENSE files in the repository root for full details. */ -import { IS_MAC, Key } from "./Keyboard"; +import { IS_MAC, Key } from "./shared-components/Keyboard"; import SettingsStore from "./settings/SettingsStore"; import SdkConfig from "./SdkConfig"; import { type IKeyBindingsProvider, type KeyBinding } from "./KeyBindingsManager"; diff --git a/src/KeyBindingsManager.ts b/src/KeyBindingsManager.ts index bef954f8feb..bdd265899d3 100644 --- a/src/KeyBindingsManager.ts +++ b/src/KeyBindingsManager.ts @@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details. import { type KeyBindingAction } from "./accessibility/KeyboardShortcuts"; import { defaultBindingsProvider } from "./KeyBindingsDefaults"; -import { IS_MAC } from "./Keyboard"; +import { IS_MAC } from "./shared-components/Keyboard"; /** * Represent a key combination. diff --git a/src/accessibility/KeyboardShortcutUtils.ts b/src/accessibility/KeyboardShortcutUtils.ts index a261bf361b1..de570214977 100644 --- a/src/accessibility/KeyboardShortcutUtils.ts +++ b/src/accessibility/KeyboardShortcutUtils.ts @@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details. */ import { type KeyCombo } from "../KeyBindingsManager"; -import { IS_MAC, Key } from "../Keyboard"; +import { IS_MAC, Key } from "../shared-components/Keyboard"; import { _t, _td } from "../languageHandler"; import PlatformPeg from "../PlatformPeg"; import SettingsStore from "../settings/SettingsStore"; diff --git a/src/accessibility/KeyboardShortcuts.ts b/src/accessibility/KeyboardShortcuts.ts index fd820206325..14c8ed633b2 100644 --- a/src/accessibility/KeyboardShortcuts.ts +++ b/src/accessibility/KeyboardShortcuts.ts @@ -10,7 +10,7 @@ Please see LICENSE files in the repository root for full details. // We need to import directly from the shared i18n instead of the language handler due to a webpack loading error import { _td, type TranslationKey } from "../shared-components/i18n"; -import { IS_MAC, IS_ELECTRON, Key } from "../Keyboard"; +import { IS_MAC, IS_ELECTRON, Key } from "../shared-components/Keyboard"; import { type IBaseSetting } from "../settings/Settings"; import { type KeyCombo } from "../KeyBindingsManager"; diff --git a/src/components/structures/AutocompleteInput.tsx b/src/components/structures/AutocompleteInput.tsx index 9767bd57619..85e2b308776 100644 --- a/src/components/structures/AutocompleteInput.tsx +++ b/src/components/structures/AutocompleteInput.tsx @@ -18,7 +18,7 @@ import classNames from "classnames"; import { SearchIcon, CloseIcon } from "@vector-im/compound-design-tokens/assets/web/icons"; import type Autocompleter from "../../autocomplete/AutocompleteProvider"; -import { Key } from "../../Keyboard"; +import { Key } from "../../shared-components/Keyboard"; import { type ICompletion } from "../../autocomplete/Autocompleter"; import AccessibleButton from "../../components/views/elements/AccessibleButton"; import useFocus from "../../hooks/useFocus"; diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 26e127f21f9..0c79b2601e9 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -21,7 +21,7 @@ import { import { type MatrixCall } from "matrix-js-sdk/src/webrtc/call"; import classNames from "classnames"; -import { isOnlyCtrlOrCmdKeyEvent, Key } from "../../Keyboard"; +import { isOnlyCtrlOrCmdKeyEvent, Key } from "../../shared-components/Keyboard"; import PageTypes from "../../PageTypes"; import MediaDeviceHandler from "../../MediaDeviceHandler"; import dis from "../../dispatcher/dispatcher"; diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index 2130f4fa216..fe5ae52c0bc 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -11,7 +11,7 @@ import React from "react"; import { ALTERNATE_KEY_NAME } from "../../accessibility/KeyboardShortcuts"; import defaultDispatcher from "../../dispatcher/dispatcher"; -import { IS_MAC, Key } from "../../Keyboard"; +import { IS_MAC, Key } from "../../shared-components/Keyboard"; import { _t } from "../../languageHandler"; import AccessibleButton from "../views/elements/AccessibleButton"; import { Action } from "../../dispatcher/actions"; diff --git a/src/components/viewmodels/right_panel/RoomSummaryCardViewModel.tsx b/src/components/viewmodels/right_panel/RoomSummaryCardViewModel.tsx index 143f3fca189..6f8d5e17f7c 100644 --- a/src/components/viewmodels/right_panel/RoomSummaryCardViewModel.tsx +++ b/src/components/viewmodels/right_panel/RoomSummaryCardViewModel.tsx @@ -30,7 +30,7 @@ import ExportDialog from "../../views/dialogs/ExportDialog"; import { ShareDialog } from "../../views/dialogs/ShareDialog"; import { type RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; import { ReportRoomDialog } from "../../views/dialogs/ReportRoomDialog"; -import { Key } from "../../../Keyboard"; +import { Key } from "../../../shared-components/Keyboard"; import { usePinnedEvents } from "../../../hooks/usePinnedEvents"; import { tagRoom } from "../../../utils/room/tagRoom"; import { inviteToRoom } from "../../../utils/room/inviteToRoom"; diff --git a/src/components/views/emojipicker/EmojiPicker.tsx b/src/components/views/emojipicker/EmojiPicker.tsx index 71659d579b4..e4a44c7a1a5 100644 --- a/src/components/views/emojipicker/EmojiPicker.tsx +++ b/src/components/views/emojipicker/EmojiPicker.tsx @@ -25,7 +25,7 @@ import { RovingTabIndexProvider, Type, } from "../../../accessibility/RovingTabIndex"; -import { Key } from "../../../Keyboard"; +import { Key } from "../../../shared-components/Keyboard"; import { clamp } from "../../../utils/numbers"; import { type ButtonEvent } from "../elements/AccessibleButton"; diff --git a/src/components/views/messages/MessageActionBar.tsx b/src/components/views/messages/MessageActionBar.tsx index eb109028d95..f283ff28104 100644 --- a/src/components/views/messages/MessageActionBar.tsx +++ b/src/components/views/messages/MessageActionBar.tsx @@ -53,7 +53,7 @@ import type ReplyChain from "../elements/ReplyChain"; import ReactionPicker from "../emojipicker/ReactionPicker"; import { CardContext } from "../right_panel/context"; import { shouldDisplayReply } from "../../../utils/Reply"; -import { Key } from "../../../Keyboard"; +import { Key } from "../../../shared-components/Keyboard"; import { ALTERNATE_KEY_NAME } from "../../../accessibility/KeyboardShortcuts"; import { Action } from "../../../dispatcher/actions"; import { type ShowThreadPayload } from "../../../dispatcher/payloads/ShowThreadPayload"; diff --git a/src/components/views/rooms/BasicMessageComposer.tsx b/src/components/views/rooms/BasicMessageComposer.tsx index 23111939c2e..d9ddc1a8e3d 100644 --- a/src/components/views/rooms/BasicMessageComposer.tsx +++ b/src/components/views/rooms/BasicMessageComposer.tsx @@ -28,7 +28,7 @@ import { getAutoCompleteCreator, type Part, type SerializedPart, Type } from ".. import { parseEvent, parsePlainTextMessage } from "../../../editor/deserialize"; import { renderModel } from "../../../editor/render"; import SettingsStore from "../../../settings/SettingsStore"; -import { IS_MAC, Key } from "../../../Keyboard"; +import { IS_MAC, Key } from "../../../shared-components/Keyboard"; import { CommandCategories, CommandMap, parseCommandString } from "../../../SlashCommands"; import Range from "../../../editor/range"; import MessageComposerFormatBar, { Formatting } from "./MessageComposerFormatBar"; diff --git a/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx b/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx index aececc300da..32b4630f845 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx @@ -11,7 +11,7 @@ import ExploreIcon from "@vector-im/compound-design-tokens/assets/web/icons/expl import SearchIcon from "@vector-im/compound-design-tokens/assets/web/icons/search"; import DialPadIcon from "@vector-im/compound-design-tokens/assets/web/icons/dial-pad"; -import { IS_MAC, Key } from "../../../../Keyboard"; +import { IS_MAC, Key } from "../../../../shared-components/Keyboard"; import { _t } from "../../../../languageHandler"; import { ALTERNATE_KEY_NAME } from "../../../../accessibility/KeyboardShortcuts"; import { shouldShowComponent } from "../../../../customisations/helpers/UIComponents"; diff --git a/src/components/views/rooms/wysiwyg_composer/hooks/usePlainTextListeners.ts b/src/components/views/rooms/wysiwyg_composer/hooks/usePlainTextListeners.ts index 57a5d1d653b..00c45040be9 100644 --- a/src/components/views/rooms/wysiwyg_composer/hooks/usePlainTextListeners.ts +++ b/src/components/views/rooms/wysiwyg_composer/hooks/usePlainTextListeners.ts @@ -11,7 +11,7 @@ import { type AllowedMentionAttributes, type MappedSuggestion } from "@vector-im import { type IEventRelation } from "matrix-js-sdk/src/matrix"; import { useSettingValue } from "../../../../../hooks/useSettings"; -import { IS_MAC, Key } from "../../../../../Keyboard"; +import { IS_MAC, Key } from "../../../../../shared-components/Keyboard"; import type Autocomplete from "../../Autocomplete"; import { handleClipboardEvent, handleEventWithAutocomplete, isEventToHandleAsClipboardEvent } from "./utils"; import { useSuggestion } from "./useSuggestion"; diff --git a/src/components/views/settings/KeyboardShortcut.tsx b/src/components/views/settings/KeyboardShortcut.tsx index 8d7dd7cdb3e..196dccea29a 100644 --- a/src/components/views/settings/KeyboardShortcut.tsx +++ b/src/components/views/settings/KeyboardShortcut.tsx @@ -10,7 +10,7 @@ import React, { type JSX } from "react"; import { ALTERNATE_KEY_NAME, KEY_ICON } from "../../../accessibility/KeyboardShortcuts"; import { type KeyCombo } from "../../../KeyBindingsManager"; -import { IS_MAC, Key } from "../../../Keyboard"; +import { IS_MAC, Key } from "../../../shared-components/Keyboard"; import { _t } from "../../../languageHandler"; interface IKeyboardKeyProps { diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx index ecf2766b209..1e4f71db293 100644 --- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx +++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx @@ -27,7 +27,7 @@ import SettingsTab from "../SettingsTab"; import { SettingsSection } from "../../shared/SettingsSection"; import LanguageDropdown from "../../../elements/LanguageDropdown"; import PlatformPeg from "../../../../../PlatformPeg"; -import { IS_MAC } from "../../../../../Keyboard"; +import { IS_MAC } from "../../../../../shared-components/Keyboard"; import SpellCheckSettings from "../../SpellCheckSettings"; import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch"; import * as TimezoneHandler from "../../../../../TimezoneHandler"; diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index d99afd90706..272c2cbf760 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -24,7 +24,7 @@ import FontSizeController from "./controllers/FontSizeController"; import SystemFontController from "./controllers/SystemFontController"; import { SettingLevel } from "./SettingLevel"; import type SettingController from "./controllers/SettingController"; -import { IS_MAC } from "../Keyboard"; +import { IS_MAC } from "../shared-components/Keyboard"; import UIFeatureController from "./controllers/UIFeatureController"; import { UIFeature } from "./UIFeature"; import { Layout } from "./enums/Layout"; diff --git a/src/Keyboard.ts b/src/shared-components/Keyboard.ts similarity index 100% rename from src/Keyboard.ts rename to src/shared-components/Keyboard.ts diff --git a/test/unit-tests/components/views/elements/AccessibleButton-test.tsx b/test/unit-tests/components/views/elements/AccessibleButton-test.tsx index 0d30c5734fd..9675795a642 100644 --- a/test/unit-tests/components/views/elements/AccessibleButton-test.tsx +++ b/test/unit-tests/components/views/elements/AccessibleButton-test.tsx @@ -10,7 +10,7 @@ import { fireEvent, getByText, render } from "jest-matrix-react"; import React from "react"; import AccessibleButton from "../../../../../src/components/views/elements/AccessibleButton"; -import { Key } from "../../../../../src/Keyboard"; +import { Key } from "../../../../../src/shared-components/Keyboard"; import { mockPlatformPeg, unmockPlatformPeg } from "../../../../test-utils"; describe("", () => { diff --git a/test/unit-tests/components/views/rooms/wysiwyg_composer/components/PlainTextComposer-test.tsx b/test/unit-tests/components/views/rooms/wysiwyg_composer/components/PlainTextComposer-test.tsx index 371960c8007..cfd4a4c50c2 100644 --- a/test/unit-tests/components/views/rooms/wysiwyg_composer/components/PlainTextComposer-test.tsx +++ b/test/unit-tests/components/views/rooms/wysiwyg_composer/components/PlainTextComposer-test.tsx @@ -13,7 +13,7 @@ import { initOnce } from "@vector-im/matrix-wysiwyg"; import { PlainTextComposer } from "../../../../../../../src/components/views/rooms/wysiwyg_composer/components/PlainTextComposer"; import * as mockUseSettingsHook from "../../../../../../../src/hooks/useSettings"; -import * as mockKeyboard from "../../../../../../../src/Keyboard"; +import * as mockKeyboard from "../../../../../../../src/shared-components/Keyboard"; import { createMocks } from "../utils"; import { ScopedRoomContextProvider } from "../../../../../../../src/contexts/ScopedRoomContext.tsx"; diff --git a/test/unit-tests/components/views/settings/KeyboardShortcut-test.tsx b/test/unit-tests/components/views/settings/KeyboardShortcut-test.tsx index edcc915e4d4..d4b87c11e20 100644 --- a/test/unit-tests/components/views/settings/KeyboardShortcut-test.tsx +++ b/test/unit-tests/components/views/settings/KeyboardShortcut-test.tsx @@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details. import React from "react"; import { render } from "jest-matrix-react"; -import { Key } from "../../../../../src/Keyboard"; +import { Key } from "../../../../../src/shared-components/Keyboard"; import { mockPlatformPeg, unmockPlatformPeg } from "../../../../test-utils/platform"; import { KeyboardKey, KeyboardShortcut } from "../../../../../src/components/views/settings/KeyboardShortcut"; diff --git a/test/unit-tests/components/views/settings/tabs/user/KeyboardUserSettingsTab-test.tsx b/test/unit-tests/components/views/settings/tabs/user/KeyboardUserSettingsTab-test.tsx index 0af6d823862..a13c55b49a8 100644 --- a/test/unit-tests/components/views/settings/tabs/user/KeyboardUserSettingsTab-test.tsx +++ b/test/unit-tests/components/views/settings/tabs/user/KeyboardUserSettingsTab-test.tsx @@ -10,7 +10,7 @@ import { render } from "jest-matrix-react"; import React from "react"; import KeyboardUserSettingsTab from "../../../../../../../src/components/views/settings/tabs/user/KeyboardUserSettingsTab"; -import { Key } from "../../../../../../../src/Keyboard"; +import { Key } from "../../../../../../../src/shared-components/Keyboard"; import { mockPlatformPeg } from "../../../../../../test-utils/platform"; const PATH_TO_KEYBOARD_SHORTCUTS = "../../../../../../../src/accessibility/KeyboardShortcuts"; From 6f4314515fe6b523b94663786564112f8933bd8f Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 8 Jul 2025 11:49:23 +0200 Subject: [PATCH 27/30] refactor: move ALTERNATE_KEY_NAME in shared-components --- src/accessibility/KeyboardShortcuts.ts | 19 +++------------- src/shared-components/KeyboardShortcuts.ts | 26 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 16 deletions(-) create mode 100644 src/shared-components/KeyboardShortcuts.ts diff --git a/src/accessibility/KeyboardShortcuts.ts b/src/accessibility/KeyboardShortcuts.ts index 14c8ed633b2..8ab92016afb 100644 --- a/src/accessibility/KeyboardShortcuts.ts +++ b/src/accessibility/KeyboardShortcuts.ts @@ -13,6 +13,9 @@ import { _td, type TranslationKey } from "../shared-components/i18n"; import { IS_MAC, IS_ELECTRON, Key } from "../shared-components/Keyboard"; import { type IBaseSetting } from "../settings/Settings"; import { type KeyCombo } from "../KeyBindingsManager"; +import { DIGITS } from "../shared-components/KeyboardShortcuts"; + +export { DIGITS, ALTERNATE_KEY_NAME } from "../shared-components/KeyboardShortcuts"; export enum KeyBindingAction { /** Send a message */ @@ -175,22 +178,6 @@ export enum CategoryName { LABS = "Labs", } -// Meta-key representing the digits [0-9] often found at the top of standard keyboard layouts -export const DIGITS = "digits"; - -export const ALTERNATE_KEY_NAME: Record = { - [Key.PAGE_UP]: _td("keyboard|page_up"), - [Key.PAGE_DOWN]: _td("keyboard|page_down"), - [Key.ESCAPE]: _td("keyboard|escape"), - [Key.ENTER]: _td("keyboard|enter"), - [Key.SPACE]: _td("keyboard|space"), - [Key.HOME]: _td("keyboard|home"), - [Key.END]: _td("keyboard|end"), - [Key.ALT]: _td("keyboard|alt"), - [Key.CONTROL]: _td("keyboard|control"), - [Key.SHIFT]: _td("keyboard|shift"), - [DIGITS]: _td("keyboard|number"), -}; export const KEY_ICON: Record = { [Key.ARROW_UP]: "↑", [Key.ARROW_DOWN]: "↓", diff --git a/src/shared-components/KeyboardShortcuts.ts b/src/shared-components/KeyboardShortcuts.ts new file mode 100644 index 00000000000..915ddf4653d --- /dev/null +++ b/src/shared-components/KeyboardShortcuts.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import { _td, type TranslationKey } from "./i18n"; +import { Key } from "./Keyboard"; + +// Meta-key representing the digits [0-9] often found at the top of standard keyboard layouts +export const DIGITS = "digits"; + +export const ALTERNATE_KEY_NAME: Record = { + [Key.PAGE_UP]: _td("keyboard|page_up"), + [Key.PAGE_DOWN]: _td("keyboard|page_down"), + [Key.ESCAPE]: _td("keyboard|escape"), + [Key.ENTER]: _td("keyboard|enter"), + [Key.SPACE]: _td("keyboard|space"), + [Key.HOME]: _td("keyboard|home"), + [Key.END]: _td("keyboard|end"), + [Key.ALT]: _td("keyboard|alt"), + [Key.CONTROL]: _td("keyboard|control"), + [Key.SHIFT]: _td("keyboard|shift"), + [DIGITS]: _td("keyboard|number"), +}; From 6752a8b1b0c6f4e0c3b0f7430b55005f3fe354ef Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 8 Jul 2025 15:58:44 +0200 Subject: [PATCH 28/30] feat: add room list search to search components --- .../RoomListSearch/RoomListSearch.module.css | 53 ++++ .../RoomListSearch/RoomListSearch.stories.tsx | 77 +++++ .../RoomListSearch/RoomListSearch.test.tsx | 36 +++ .../RoomListSearch/RoomListSearch.tsx | 96 +++++++ .../RoomListSearch.test.tsx.snap | 269 ++++++++++++++++++ .../room-list/RoomListSearch/index.ts | 8 + 6 files changed, 539 insertions(+) create mode 100644 src/shared-components/room-list/RoomListSearch/RoomListSearch.module.css create mode 100644 src/shared-components/room-list/RoomListSearch/RoomListSearch.stories.tsx create mode 100644 src/shared-components/room-list/RoomListSearch/RoomListSearch.test.tsx create mode 100644 src/shared-components/room-list/RoomListSearch/RoomListSearch.tsx create mode 100644 src/shared-components/room-list/RoomListSearch/__snapshots__/RoomListSearch.test.tsx.snap create mode 100644 src/shared-components/room-list/RoomListSearch/index.ts diff --git a/src/shared-components/room-list/RoomListSearch/RoomListSearch.module.css b/src/shared-components/room-list/RoomListSearch/RoomListSearch.module.css new file mode 100644 index 00000000000..d1b57fb5045 --- /dev/null +++ b/src/shared-components/room-list/RoomListSearch/RoomListSearch.module.css @@ -0,0 +1,53 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +.container { + /* From figma, this should be aligned with the room header */ + flex: 0 0 64px; + box-sizing: border-box; + border-bottom: var(--cpd-border-width-1) solid var(--cpd-color-bg-subtle-primary); + padding: 0 var(--cpd-space-3x); + + svg { + fill: var(--cpd-color-icon-secondary); + } +} + +.searchBar { + /* The search button should take all the remaining space */ + flex: 1; + font: var(--cpd-font-body-md-regular); + min-width: 0; + + span { + flex: 1; + color: var(--cpd-color-text-secondary); + + kbd { + font-family: inherit; + } + + /* Shrink and truncate the search text */ + white-space: nowrap; + overflow: hidden; + + } +} + +.searchText { + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + text-align: start; +} + +.button:hover { + svg { + fill: var(--cpd-color-icon-primary); + } +} diff --git a/src/shared-components/room-list/RoomListSearch/RoomListSearch.stories.tsx b/src/shared-components/room-list/RoomListSearch/RoomListSearch.stories.tsx new file mode 100644 index 00000000000..98f56e39357 --- /dev/null +++ b/src/shared-components/room-list/RoomListSearch/RoomListSearch.stories.tsx @@ -0,0 +1,77 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import React, { type JSX, type MouseEventHandler, useMemo } from "react"; +import { fn } from "storybook/test"; +import { type Meta, type StoryFn } from "@storybook/react-vite"; + +import { + RoomListSearch as RoomListSearchComponent, + type RoomListSearchSnapshot, + type RoomListSearchViewModel, +} from "./RoomListSearch"; +import { MockViewModel } from "../../MockViewModel"; + +interface Props extends RoomListSearchSnapshot { + onSearchClick: MouseEventHandler; + onDialPadClick: MouseEventHandler; + onExploreClick: MouseEventHandler; +} + +function Wrapper(props: Props): JSX.Element { + const vm = useMemo(() => { + const { displayExploreButton, displayDialButton, ...actions } = props; + const viewModel = new MockViewModel({ + displayExploreButton, + displayDialButton, + }) as unknown as RoomListSearchViewModel; + Object.assign(viewModel, actions); + + return viewModel; + }, [props]); + return ; +} + +export default { + title: "RoomList/RoomListSearch", + component: Wrapper, + tags: ["autodocs"], + args: { + displayExploreButton: true, + displayDialButton: true, + onSearchClick: fn(), + onDialPadClick: fn(), + onExploreClick: fn(), + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta; + +const Template: StoryFn = (args) => ; + +export const Default = Template.bind({}); + +export const HideExploreButton = Template.bind({}); +HideExploreButton.args = { + displayExploreButton: false, +}; + +export const HideDialButton = Template.bind({}); +HideDialButton.args = { + displayDialButton: false, +}; + +export const HideAllButtons = Template.bind({}); +HideAllButtons.args = { + displayExploreButton: false, + displayDialButton: false, +}; diff --git a/src/shared-components/room-list/RoomListSearch/RoomListSearch.test.tsx b/src/shared-components/room-list/RoomListSearch/RoomListSearch.test.tsx new file mode 100644 index 00000000000..209c9ee5061 --- /dev/null +++ b/src/shared-components/room-list/RoomListSearch/RoomListSearch.test.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import { composeStories } from "@storybook/react-vite"; +import { render } from "jest-matrix-react"; +import React from "react"; + +import * as stories from "./RoomListSearch.stories.tsx"; + +const { Default, HideExploreButton, HideDialButton, HideAllButtons } = composeStories(stories); + +describe("RoomListSearch", () => { + it("renders the search bar with all the buttons", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + it("renders the search bar with the explore button hidden", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + it("renders the search bar with the dial button hidden", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + it("renders the search bar with all the button hidden", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/src/shared-components/room-list/RoomListSearch/RoomListSearch.tsx b/src/shared-components/room-list/RoomListSearch/RoomListSearch.tsx new file mode 100644 index 00000000000..5904b6f9d56 --- /dev/null +++ b/src/shared-components/room-list/RoomListSearch/RoomListSearch.tsx @@ -0,0 +1,96 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +import React, { type JSX, type MouseEventHandler } from "react"; +import { Button } from "@vector-im/compound-web"; +import ExploreIcon from "@vector-im/compound-design-tokens/assets/web/icons/explore"; +import SearchIcon from "@vector-im/compound-design-tokens/assets/web/icons/search"; +import DialPadIcon from "@vector-im/compound-design-tokens/assets/web/icons/dial-pad"; + +import { Flex } from "../../Flex"; +import { IS_MAC, Key } from "../../Keyboard"; +import styles from "./RoomListSearch.module.css"; +import { _t } from "../../i18n"; +import type { ViewModel } from "../../ViewModel"; +import { useViewModel } from "../../useViewModel"; +import { ALTERNATE_KEY_NAME } from "../../KeyboardShortcuts"; + +export interface RoomListSearchSnapshot { + /** + * Whether the Explore button should be displayed. + */ + displayExploreButton: boolean; + /** + * Whether the Dial Pad button should be displayed. + */ + displayDialButton: boolean; +} + +export interface RoomListSearchViewModel extends ViewModel { + /** + * Callback for when the search button is clicked. + */ + onSearchClick: MouseEventHandler; + /** + * Callback for when the Dial Pad button is clicked. + */ + onDialPadClick: MouseEventHandler; + /** + * Callback for when the Explore button is clicked. + */ + onExploreClick: MouseEventHandler; +} + +interface RoomListSearchProps { + vm: RoomListSearchViewModel; +} + +/** + * A search component to be displayed at the top of the room list + */ +export function RoomListSearch({ vm }: RoomListSearchProps): JSX.Element { + const { displayExploreButton, displayDialButton } = useViewModel(vm); + + return ( + + + {displayDialButton && ( + +
+ + +`; + +exports[`RoomListSearch renders the search bar with all the buttons 1`] = ` +
+
+
+ + + +
+
+
+`; + +exports[`RoomListSearch renders the search bar with the dial button hidden 1`] = ` +
+
+
+ + +
+
+
+`; + +exports[`RoomListSearch renders the search bar with the explore button hidden 1`] = ` +
+
+
+ + +
+
+
+`; diff --git a/src/shared-components/room-list/RoomListSearch/index.ts b/src/shared-components/room-list/RoomListSearch/index.ts new file mode 100644 index 00000000000..e0228569535 --- /dev/null +++ b/src/shared-components/room-list/RoomListSearch/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +export { RoomListSearch } from "./RoomListSearch"; From 5fcba8d505463cb83f9e32daf9ca8c81ed051904 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 8 Jul 2025 16:44:25 +0200 Subject: [PATCH 29/30] fix: give access to `ViewModelSubscriptions#listeners` --- src/viewmodels/ViewModelSubscriptions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/viewmodels/ViewModelSubscriptions.ts b/src/viewmodels/ViewModelSubscriptions.ts index ff263b2b5c3..d1f4fb01949 100644 --- a/src/viewmodels/ViewModelSubscriptions.ts +++ b/src/viewmodels/ViewModelSubscriptions.ts @@ -6,7 +6,7 @@ Please see LICENSE files in the repository root for full details. */ export class ViewModelSubscriptions { - private listeners = new Set<() => void>(); + public listeners = new Set<() => void>(); public constructor(private updateSubscription: () => void) {} From 0055714b118a2682ce8115bd40463d1a25f1da16 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Tue, 8 Jul 2025 16:19:35 +0200 Subject: [PATCH 30/30] refactor: use `RoomListSearch` in room list panel --- src/components/structures/LeftPanel.tsx | 2 +- .../rooms/RoomListPanel/RoomListPanel.tsx | 12 +- .../rooms/RoomListPanel/RoomListSearch.tsx | 83 +------------- .../room-list/RoomListSearchViewModel.ts | 108 ++++++++++++++++++ 4 files changed, 117 insertions(+), 88 deletions(-) create mode 100644 src/viewmodels/room-list/RoomListSearchViewModel.ts diff --git a/src/components/structures/LeftPanel.tsx b/src/components/structures/LeftPanel.tsx index 3bd2518c8ad..c2b6bc21ebf 100644 --- a/src/components/structures/LeftPanel.tsx +++ b/src/components/structures/LeftPanel.tsx @@ -391,7 +391,7 @@ export default class LeftPanel extends React.Component { return (
- +
); diff --git a/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx b/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx index b09636cddf2..ef6d566694e 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListPanel.tsx @@ -15,18 +15,10 @@ import { RoomListView } from "./RoomListView"; import { Flex } from "../../../../shared-components/Flex"; import { _t } from "../../../../languageHandler"; -type RoomListPanelProps = { - /** - * Current active space - * See {@link RoomListSearch} - */ - activeSpace: string; -}; - /** * The panel of the room list */ -export const RoomListPanel: React.FC = ({ activeSpace }) => { +export const RoomListPanel: React.FC = () => { const displayRoomSearch = shouldShowComponent(UIComponent.FilterContainer); return ( @@ -37,7 +29,7 @@ export const RoomListPanel: React.FC = ({ activeSpace }) => align="stretch" aria-label={_t("room_list|list_title")} > - {displayRoomSearch && } + {displayRoomSearch && } diff --git a/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx b/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx index 32b4630f845..b5f702b4b2f 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListSearch.tsx @@ -5,87 +5,16 @@ * Please see LICENSE files in the repository root for full details. */ -import React, { type JSX } from "react"; -import { Button } from "@vector-im/compound-web"; -import ExploreIcon from "@vector-im/compound-design-tokens/assets/web/icons/explore"; -import SearchIcon from "@vector-im/compound-design-tokens/assets/web/icons/search"; -import DialPadIcon from "@vector-im/compound-design-tokens/assets/web/icons/dial-pad"; +import React, { type JSX, useMemo } from "react"; -import { IS_MAC, Key } from "../../../../shared-components/Keyboard"; -import { _t } from "../../../../languageHandler"; -import { ALTERNATE_KEY_NAME } from "../../../../accessibility/KeyboardShortcuts"; -import { shouldShowComponent } from "../../../../customisations/helpers/UIComponents"; -import { UIComponent } from "../../../../settings/UIFeature"; -import { MetaSpace } from "../../../../stores/spaces"; -import { Action } from "../../../../dispatcher/actions"; -import PosthogTrackers from "../../../../PosthogTrackers"; -import defaultDispatcher from "../../../../dispatcher/dispatcher"; -import { Flex } from "../../../../shared-components/Flex"; -import { useTypedEventEmitterState } from "../../../../hooks/useEventEmitter"; -import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../../../LegacyCallHandler"; - -type RoomListSearchProps = { - /** - * Current active space - * The explore button is only displayed in the Home meta space - */ - activeSpace: string; -}; +import { RoomListSearchViewModel } from "../../../../viewmodels/room-list/RoomListSearchViewModel"; +import { RoomListSearch as RoomListSearchView } from "../../../../shared-components/room-list/RoomListSearch"; /** * A search component to be displayed at the top of the room list * The `Explore` button is displayed only in the Home meta space and when UIComponent.ExploreRooms is enabled. */ -export function RoomListSearch({ activeSpace }: RoomListSearchProps): JSX.Element { - const displayExploreButton = activeSpace === MetaSpace.Home && shouldShowComponent(UIComponent.ExploreRooms); - // We only display the dial button if the user is can make PSTN calls - const displayDialButton = useTypedEventEmitterState( - LegacyCallHandler.instance, - LegacyCallHandlerEvent.ProtocolSupport, - () => LegacyCallHandler.instance.getSupportsPstnProtocol(), - ); - - return ( - - - {displayDialButton && ( -