Skip to content
6 changes: 6 additions & 0 deletions .changeset/silent-ducks-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@clerk/ui': patch
'@clerk/shared': patch
---

Remove `virtual` from the `routing` option. The `virtual` value is only used internally and should not be part of the public API.
2 changes: 1 addition & 1 deletion packages/shared/src/types/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ export type SetActive = (setActiveParams: SetActiveParams) => Promise<void>;

export type RoutingOptions =
| { path: string | undefined; routing?: Extract<RoutingStrategy, 'path'> }
| { path?: never; routing?: Extract<RoutingStrategy, 'hash' | 'virtual'> };
| { path?: never; routing?: Extract<RoutingStrategy, 'hash'> };

export type SignInProps = RoutingOptions & {
/**
Expand Down
27 changes: 16 additions & 11 deletions packages/ui/src/components/OrganizationProfile/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@ import { useOrganization } from '@clerk/shared/react';
import type { OrganizationProfileModalProps, OrganizationProfileProps } from '@clerk/shared/types';
import React from 'react';

import { withCardStateProvider } from '@/ui/elements/contexts';
import { NavbarMenuButtonRow } from '@/ui/elements/Navbar';
import { ProfileCard } from '@/ui/elements/ProfileCard';
import { ORGANIZATION_PROFILE_CARD_SCROLLBOX_ID } from '@/constants';
import { OrganizationProfileContext, SubscriberTypeContext, withCoreUserGuard } from '@/contexts';
import { Flow, localizationKeys } from '@/customizables';
import { withCardStateProvider } from '@/elements/contexts';
import { NavbarMenuButtonRow } from '@/elements/Navbar';
import { ProfileCard } from '@/elements/ProfileCard';
import type { WithInternalRouting } from '@/internal';
import { Route, Switch } from '@/router';
import type { OrganizationProfileCtx } from '@/types';

import { ORGANIZATION_PROFILE_CARD_SCROLLBOX_ID } from '../../constants';
import { OrganizationProfileContext, SubscriberTypeContext, withCoreUserGuard } from '../../contexts';
import { Flow, localizationKeys } from '../../customizables';
import { Route, Switch } from '../../router';
import type { OrganizationProfileCtx } from '../../types';
import { OrganizationProfileNavbar } from './OrganizationProfileNavbar';
import { OrganizationProfileRoutes } from './OrganizationProfileRoutes';

const _OrganizationProfile = (_: OrganizationProfileProps) => {
const OrganizationProfileInternal = () => {
const { organization } = useOrganization();

if (!organization) {
Expand Down Expand Up @@ -55,7 +56,11 @@ const AuthenticatedRoutes = withCoreUserGuard(() => {
);
});

export const OrganizationProfile = withCardStateProvider(_OrganizationProfile);
export const OrganizationProfile: React.ComponentType<OrganizationProfileProps> =
withCardStateProvider(OrganizationProfileInternal);

const InternalOrganizationProfile: React.ComponentType<WithInternalRouting<OrganizationProfileProps>> =
withCardStateProvider(OrganizationProfileInternal);
Comment on lines +59 to +63
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the type definitions for WithInternalRouting and base props
# Also check the withCardStateProvider implementation

echo "=== WithInternalRouting type definition ==="
rg -n "type WithInternalRouting" --type=ts --type=tsx -A 3

echo -e "\n=== OrganizationProfileProps type definition ==="
rg -n "type OrganizationProfileProps" --type=ts --type=tsx -A 5

echo -e "\n=== OrganizationProfileCtx type definition ==="
rg -n "type OrganizationProfileCtx" --type=ts --type=tsx -A 5

echo -e "\n=== withCardStateProvider implementation ==="
rg -n "export.*withCardStateProvider|function withCardStateProvider" --type=ts --type=tsx -A 10

Repository: clerk/javascript

Length of output: 376


🏁 Script executed:

#!/bin/bash
# Check the current file to see actual JSDoc presence and context
echo "=== File content around lines 59-63 ==="
sed -n '50,70p' packages/ui/src/components/OrganizationProfile/index.tsx

Repository: clerk/javascript

Length of output: 865


🏁 Script executed:

#!/bin/bash
# Retry without file type flags to find type definitions
echo "=== WithInternalRouting type definition ==="
rg "type WithInternalRouting" -A 3

echo -e "\n=== OrganizationProfileProps type definition ==="
rg "type OrganizationProfileProps\s*=" -A 5

echo -e "\n=== withCardStateProvider implementation ==="
rg "withCardStateProvider\s*=" -B 2 -A 10

Repository: clerk/javascript

Length of output: 1797


🏁 Script executed:

#!/bin/bash
# Look for JSDoc on the OrganizationProfile export
echo "=== Checking for JSDoc comments before export ==="
sed -n '45,62p' packages/ui/src/components/OrganizationProfile/index.tsx

Repository: clerk/javascript

Length of output: 804


🏁 Script executed:

#!/bin/bash
# Find where WithInternalRouting is defined
echo "=== Finding WithInternalRouting definition ==="
fd -e ts -e tsx | xargs grep -l "WithInternalRouting" | head -5

Repository: clerk/javascript

Length of output: 427


🏁 Script executed:

#!/bin/bash
# Find where withCardStateProvider is defined
echo "=== Finding withCardStateProvider ==="
fd -e ts -e tsx | xargs grep -l "withCardStateProvider" | head -10

Repository: clerk/javascript

Length of output: 729


Add JSDoc documentation for the public OrganizationProfile export.

This is a public API that must be documented with JSDoc per coding guidelines. Include a description of the component's purpose, usage example, and prop documentation.

The type safety pattern with withCardStateProvider accepting both OrganizationProfileProps and WithInternalRouting<OrganizationProfileProps> is intentional by design, as evidenced by the @ts-expect-error in the HOC implementation that deliberately bridges these type signatures.

🤖 Prompt for AI Agents
In packages/ui/src/components/OrganizationProfile/index.tsx around lines 59 to
63, the public export OrganizationProfile lacks required JSDoc; add a JSDoc
block immediately above the export that documents the component’s purpose (brief
description), a short usage example showing how to import and render it, and
@param/@props tags describing OrganizationProfileProps properties (their types
and meanings) along with any notes about HOC typing/WithInternalRouting
behavior; keep the existing withCardStateProvider usage and do not change the
implementation—only add the comprehensive JSDoc for the public API.


export const OrganizationProfileModal = (props: OrganizationProfileModalProps): JSX.Element => {
const organizationProfileProps: OrganizationProfileCtx = {
Expand All @@ -70,7 +75,7 @@ export const OrganizationProfileModal = (props: OrganizationProfileModalProps):
<OrganizationProfileContext.Provider value={organizationProfileProps}>
{/*TODO: Used by InvisibleRootBox, can we simplify? */}
<div>
<OrganizationProfile {...organizationProfileProps} />
<InternalOrganizationProfile {...organizationProfileProps} />
</div>
</OrganizationProfileContext.Provider>
</Route>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import type { SignInFactor } from '@clerk/shared/types';
import type { SignInSecondFactor } from '@clerk/shared/types';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add JSDoc documentation to the exported getButtonLabel function.

The function at line 96 is exported and lacks JSDoc comments. Per the coding guidelines for packages/**/src/**/*.{ts,tsx}, all public APIs must be documented with @param, @returns, and other relevant tags.

Additionally, verify that all components calling this component with onFactorSelected or invoking getButtonLabel pass instances compatible with SignInSecondFactor (PhoneCodeFactor, TOTPFactor, BackupCodeFactor, EmailCodeFactor, or EmailLinkFactor), since this narrows the accepted type from the previous SignInFactor.

🤖 Prompt for AI Agents
packages/ui/src/components/SignIn/SignInFactorTwoAlternativeMethods.tsx around
line 96: the exported function getButtonLabel is missing JSDoc and the review
requires documenting public APIs and tightening the accepted factor type to
SignInSecondFactor; add a JSDoc block above getButtonLabel that includes a brief
description, an @param tag describing the parameter as SignInSecondFactor
(enumerating allowed variants: PhoneCodeFactor, TOTPFactor, BackupCodeFactor,
EmailCodeFactor, EmailLinkFactor) and what each branch yields, and an @returns
tag describing the returned string; then update the function signature (and any
exported type annotations) to accept SignInSecondFactor instead of the broader
SignInFactor and run a quick grep/TS check to find all call sites using
onFactorSelected or calling getButtonLabel and ensure they pass only the allowed
second-factor variants, updating their types or narrow-casting where necessary
to satisfy the new signature.

import React from 'react';

import { ArrowBlockButton } from '@/ui/elements/ArrowBlockButton';
import { Card } from '@/ui/elements/Card';
import { Header } from '@/ui/elements/Header';
import { backupCodePrefFactorComparator } from '@/ui/utils/factorSorting';
import { formatSafeIdentifier } from '@/ui/utils/formatSafeIdentifier';
import { useCoreSignIn } from '@/contexts';
import type { LocalizationKey } from '@/customizables';
import { Col, descriptors, Flow, localizationKeys } from '@/customizables';
import { ArrowBlockButton } from '@/elements/ArrowBlockButton';
import { Card } from '@/elements/Card';
import { useCardState } from '@/elements/contexts';
import { Header } from '@/elements/Header';
import { backupCodePrefFactorComparator } from '@/utils/factorSorting';
import { formatSafeIdentifier } from '@/utils/formatSafeIdentifier';

import { useCoreSignIn } from '../../contexts';
import type { LocalizationKey } from '../../customizables';
import { Col, descriptors, Flow, localizationKeys } from '../../customizables';
import { useCardState } from '../../elements/contexts';
import { HavingTrouble } from './HavingTrouble';

export type AlternativeMethodsProps = {
onBackLinkClick: React.MouseEventHandler | undefined;
onFactorSelected: (factor: SignInFactor) => void;
onFactorSelected: (factor: SignInSecondFactor) => void;
};

export const SignInFactorTwoAlternativeMethods = (props: AlternativeMethodsProps) => {
Expand Down Expand Up @@ -93,7 +93,7 @@ const AlternativeMethodsList = (props: AlternativeMethodsProps & { onHavingTroub
);
};

export function getButtonLabel(factor: SignInFactor): LocalizationKey {
export function getButtonLabel(factor: SignInSecondFactor): LocalizationKey {
switch (factor.strategy) {
case 'phone_code':
return localizationKeys('signIn.alternativeMethods.blockButton__phoneCode', {
Expand All @@ -112,6 +112,7 @@ export function getButtonLabel(factor: SignInFactor): LocalizationKey {
identifier: formatSafeIdentifier(factor.safeIdentifier) || '',
});
default:
throw new Error(`Invalid sign in strategy: "${factor.strategy}"`);
((_: never) => _)(factor);
throw new Error('Invalid sign in strategy');
}
}
21 changes: 12 additions & 9 deletions packages/ui/src/components/SignIn/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@ import { useClerk } from '@clerk/shared/react';
import type { SignInModalProps, SignInProps } from '@clerk/shared/types';
import React from 'react';

import { SignInEmailLinkFlowComplete, SignUpEmailLinkFlowComplete } from '@/ui/common/EmailLinkCompleteFlowCard';
import { SignInEmailLinkFlowComplete, SignUpEmailLinkFlowComplete } from '@/common/EmailLinkCompleteFlowCard';
import {
SignInContext,
SignUpContext,
useSignInContext,
useSignUpContext,
withCoreSessionSwitchGuard,
} from '@/ui/contexts';
import { Flow } from '@/ui/customizables';
import { useFetch } from '@/ui/hooks';
import { usePreloadTasks } from '@/ui/hooks/usePreloadTasks';
import { SessionTasks as LazySessionTasks } from '@/ui/lazyModules/components';
import { Route, Switch, VIRTUAL_ROUTER_BASE_PATH } from '@/ui/router';
import type { SignUpCtx } from '@/ui/types';
} from '@/contexts';
import { Flow } from '@/customizables';
import { useFetch } from '@/hooks';
import { usePreloadTasks } from '@/hooks/usePreloadTasks';
import type { WithInternalRouting } from '@/internal';
import { SessionTasks as LazySessionTasks } from '@/lazyModules/components';
import { Route, Switch, VIRTUAL_ROUTER_BASE_PATH } from '@/router';
import type { SignUpCtx } from '@/types';
import { normalizeRoutingOptions } from '@/utils/normalizeRoutingOptions';

import {
Expand Down Expand Up @@ -195,6 +196,8 @@ SignInRoutes.displayName = 'SignIn';

export const SignIn: React.ComponentType<SignInProps> = withCoreSessionSwitchGuard(SignInRoot);

const InternalSignIn: React.ComponentType<WithInternalRouting<SignInProps>> = withCoreSessionSwitchGuard(SignInRoot);

export const SignInModal = (props: SignInModalProps): JSX.Element => {
const signInProps = {
signUpUrl: `/${VIRTUAL_ROUTER_BASE_PATH}/sign-up`,
Expand All @@ -214,7 +217,7 @@ export const SignInModal = (props: SignInModalProps): JSX.Element => {
>
{/*TODO: Used by InvisibleRootBox, can we simplify? */}
<div>
<SignIn
<InternalSignIn
{...signInProps}
routing='virtual'
/>
Expand Down
17 changes: 10 additions & 7 deletions packages/ui/src/components/SignUp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { useClerk } from '@clerk/shared/react';
import type { SignUpModalProps, SignUpProps } from '@clerk/shared/types';
import React from 'react';

import { usePreloadTasks } from '@/ui/hooks/usePreloadTasks';
import { SignUpEmailLinkFlowComplete } from '@/common/EmailLinkCompleteFlowCard';
import { SignUpContext, useSignUpContext, withCoreSessionSwitchGuard } from '@/contexts';
import { Flow } from '@/customizables';
import { usePreloadTasks } from '@/hooks/usePreloadTasks';
import type { WithInternalRouting } from '@/internal';
import { SessionTasks as LazySessionTasks } from '@/lazyModules/components';
import { Route, Switch, VIRTUAL_ROUTER_BASE_PATH } from '@/router';

import { SignUpEmailLinkFlowComplete } from '../../common/EmailLinkCompleteFlowCard';
import { SignUpContext, useSignUpContext, withCoreSessionSwitchGuard } from '../../contexts';
import { Flow } from '../../customizables';
import { SessionTasks as LazySessionTasks } from '../../lazyModules/components';
import { Route, Switch, VIRTUAL_ROUTER_BASE_PATH } from '../../router';
import { SignUpContinue } from './SignUpContinue';
import { SignUpEnterpriseConnections } from './SignUpEnterpriseConnections';
import { SignUpSSOCallback } from './SignUpSSOCallback';
Expand Down Expand Up @@ -101,6 +102,8 @@ SignUpRoutes.displayName = 'SignUp';

export const SignUp: React.ComponentType<SignUpProps> = withCoreSessionSwitchGuard(SignUpRoutes);

const InternalSignUp: React.ComponentType<WithInternalRouting<SignUpProps>> = withCoreSessionSwitchGuard(SignUpRoutes);

export const SignUpModal = (props: SignUpModalProps): JSX.Element => {
const signUpProps = {
signInUrl: `/${VIRTUAL_ROUTER_BASE_PATH}/sign-in`,
Expand All @@ -120,7 +123,7 @@ export const SignUpModal = (props: SignUpModalProps): JSX.Element => {
>
{/*TODO: Used by InvisibleRootBox, can we simplify? */}
<div>
<SignUp
<InternalSignUp
{...signUpProps}
routing='virtual'
/>
Expand Down
26 changes: 15 additions & 11 deletions packages/ui/src/components/UserProfile/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import type { UserProfileModalProps, UserProfileProps } from '@clerk/shared/types';
import React from 'react';

import { withCardStateProvider } from '@/ui/elements/contexts';
import { NavbarMenuButtonRow } from '@/ui/elements/Navbar';
import { ProfileCard } from '@/ui/elements/ProfileCard';
import { USER_PROFILE_CARD_SCROLLBOX_ID } from '@/constants';
import { UserProfileContext, withCoreUserGuard } from '@/contexts';
import { Flow, localizationKeys } from '@/customizables';
import { withCardStateProvider } from '@/elements/contexts';
import { NavbarMenuButtonRow } from '@/elements/Navbar';
import { ProfileCard } from '@/elements/ProfileCard';
import type { WithInternalRouting } from '@/internal';
import { Route, Switch } from '@/router';
import type { UserProfileCtx } from '@/types';

import { USER_PROFILE_CARD_SCROLLBOX_ID } from '../../constants';
import { UserProfileContext, withCoreUserGuard } from '../../contexts';
import { Flow, localizationKeys } from '../../customizables';
import { Route, Switch } from '../../router';
import type { UserProfileCtx } from '../../types';
import { UserProfileNavbar } from './UserProfileNavbar';
import { UserProfileRoutes } from './UserProfileRoutes';
import { VerificationSuccessPage } from './VerifyWithLink';

const _UserProfile = (_: UserProfileProps) => {
const _UserProfile = () => {
return (
<Flow.Root flow='userProfile'>
<Flow.Part>
Expand Down Expand Up @@ -49,7 +50,10 @@ const AuthenticatedRoutes = withCoreUserGuard(() => {
);
});

export const UserProfile = withCardStateProvider(_UserProfile);
export const UserProfile: React.ComponentType<UserProfileProps> = withCardStateProvider(_UserProfile);

const InternalUserProfile: React.ComponentType<WithInternalRouting<UserProfileProps>> =
withCardStateProvider(_UserProfile);

export const UserProfileModal = (props: UserProfileModalProps): JSX.Element => {
const userProfileProps: UserProfileCtx = {
Expand All @@ -64,7 +68,7 @@ export const UserProfileModal = (props: UserProfileModalProps): JSX.Element => {
<UserProfileContext.Provider value={userProfileProps}>
{/*TODO: Used by InvisibleRootBox, can we simplify? */}
<div>
<UserProfile {...userProfileProps} />
<InternalUserProfile {...userProfileProps} />
</div>
</UserProfileContext.Provider>
</Route>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { SessionVerificationResource, SessionVerificationSecondFactor } from '@clerk/shared/types';
import React, { useEffect, useMemo } from 'react';
import { useEffect, useMemo } from 'react';

import { withCardStateProvider } from '@/ui/elements/contexts';
import { LoadingCard } from '@/ui/elements/LoadingCard';
import { withCardStateProvider } from '@/elements/contexts';
import { LoadingCard } from '@/elements/LoadingCard';
import { useRouter } from '@/router';

import { useRouter } from '../../router';
import { useSecondFactorSelection } from '../SignIn/useSecondFactorSelection';
import { secondFactorsAreEqual } from './useReverificationAlternativeStrategies';
import { UserVerificationFactorTwoTOTP } from './UserVerificationFactorTwoTOTP';
Expand Down
10 changes: 6 additions & 4 deletions packages/ui/src/components/UserVerification/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { __internal_UserVerificationModalProps, __internal_UserVerificationProps } from '@clerk/shared/types';
import React, { useEffect } from 'react';

import { UserVerificationContext, withCoreSessionSwitchGuard } from '../../contexts';
import { Flow } from '../../customizables';
import { Route, Switch } from '../../router';
import { UserVerificationContext, withCoreSessionSwitchGuard } from '@/contexts';
import { Flow } from '@/customizables';
import type { WithInternalRouting } from '@/internal';
import { Route, Switch } from '@/router';

import { UserVerificationFactorOne } from './UserVerificationFactorOne';
import { UserVerificationFactorTwo } from './UserVerificationFactorTwo';
import { useUserVerificationSession } from './useUserVerificationSession';
Expand Down Expand Up @@ -31,7 +33,7 @@ function UserVerificationRoutes(): JSX.Element {

UserVerificationRoutes.displayName = 'UserVerification';

const UserVerification: React.ComponentType<__internal_UserVerificationProps> =
const UserVerification: React.ComponentType<WithInternalRouting<__internal_UserVerificationProps>> =
withCoreSessionSwitchGuard(UserVerificationRoutes);

const UserVerificationModal = (props: __internal_UserVerificationModalProps): JSX.Element => {
Expand Down
6 changes: 3 additions & 3 deletions packages/ui/src/customizables/parseAppearance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ export type ParsedInternalTheme = InternalTheme;
export type ParsedOptions = Required<Options>;
export type ParsedCaptcha = Required<CaptchaAppearanceOptions>;

type PublicAppearanceTopLevelKey = keyof Omit<
Appearance,
'theme' | 'elements' | 'layout' | 'variables' | 'captcha' | 'cssLayerName'
type PublicAppearanceTopLevelKey = Exclude<
keyof Appearance,
keyof Theme | 'captcha' | 'cssLayerName' | 'elements' | 'layout' | 'theme' | 'variables'
>;

export type AppearanceCascade = {
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/internal/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Appearance } from './appearance';

export type { ComponentControls, MountComponentRenderer } from '../Components';
export type { WithInternalRouting } from './routing';

/**
* Extracts the appearance type from a Ui object. We got 3 cases:
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/internal/routing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import type { RoutingStrategy } from '@clerk/shared/types';

export type WithInternalRouting<T> =
| (Omit<T, 'routing' | 'path'> & { path: string | undefined; routing?: Extract<RoutingStrategy, 'path'> })
| (Omit<T, 'routing' | 'path'> & { path?: never; routing?: Extract<RoutingStrategy, 'hash' | 'virtual'> });
14 changes: 8 additions & 6 deletions packages/ui/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import type {
WaitlistProps,
} from '@clerk/shared/types';

import type { WithInternalRouting } from './internal';

export type {
__internal_OAuthConsentProps,
__internal_UserVerificationProps,
Expand Down Expand Up @@ -65,23 +67,23 @@ export type AvailableComponentProps =
type ComponentMode = 'modal' | 'mounted';
type SignInMode = 'modal' | 'redirect';

export type SignInCtx = SignInProps & {
export type SignInCtx = WithInternalRouting<SignInProps> & {
componentName: 'SignIn';
mode?: ComponentMode;
} & SignInFallbackRedirectUrl &
SignInForceRedirectUrl;

export type UserVerificationCtx = __internal_UserVerificationProps & {
export type UserVerificationCtx = WithInternalRouting<__internal_UserVerificationProps> & {
componentName: 'UserVerification';
mode?: ComponentMode;
};

export type UserProfileCtx = UserProfileProps & {
export type UserProfileCtx = WithInternalRouting<UserProfileProps> & {
componentName: 'UserProfile';
mode?: ComponentMode;
};

export type SignUpCtx = SignUpProps & {
export type SignUpCtx = WithInternalRouting<SignUpProps> & {
componentName: 'SignUp';
mode?: ComponentMode;
emailLinkRedirectUrl?: string;
Expand All @@ -98,12 +100,12 @@ export type UserAvatarCtx = UserAvatarProps & {
componentName: 'UserAvatar';
};

export type OrganizationProfileCtx = OrganizationProfileProps & {
export type OrganizationProfileCtx = WithInternalRouting<OrganizationProfileProps> & {
componentName: 'OrganizationProfile';
mode?: ComponentMode;
};

export type CreateOrganizationCtx = CreateOrganizationProps & {
export type CreateOrganizationCtx = WithInternalRouting<CreateOrganizationProps> & {
componentName: 'CreateOrganization';
mode?: ComponentMode;
};
Expand Down
Loading