From 717b625b58e2594b13df80235cf9949b86039a0e Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Mon, 20 Jan 2025 15:23:31 -0600 Subject: [PATCH 1/3] remove new UI renderer --- packages/clerk-js/jest.setup.ts | 1 - packages/clerk-js/rspack.config.js | 1 - packages/clerk-js/src/core/clerk.ts | 61 ++++-------- packages/clerk-js/src/ui/new/index.tsx | 100 -------------------- packages/clerk-js/src/ui/new/renderer.tsx | 107 ---------------------- packages/clerk-js/src/ui/new/types.ts | 12 --- packages/clerk-js/turbo.json | 1 - 7 files changed, 18 insertions(+), 265 deletions(-) delete mode 100644 packages/clerk-js/src/ui/new/index.tsx delete mode 100644 packages/clerk-js/src/ui/new/renderer.tsx delete mode 100644 packages/clerk-js/src/ui/new/types.ts diff --git a/packages/clerk-js/jest.setup.ts b/packages/clerk-js/jest.setup.ts index cf496bb4130..c9637424917 100644 --- a/packages/clerk-js/jest.setup.ts +++ b/packages/clerk-js/jest.setup.ts @@ -35,7 +35,6 @@ if (typeof window !== 'undefined') { global.__PKG_NAME__ = ''; global.__PKG_VERSION__ = ''; - global.BUILD_ENABLE_NEW_COMPONENTS = ''; //@ts-expect-error global.IntersectionObserver = class IntersectionObserver { diff --git a/packages/clerk-js/rspack.config.js b/packages/clerk-js/rspack.config.js index 75d8517854d..fd806d5a15d 100644 --- a/packages/clerk-js/rspack.config.js +++ b/packages/clerk-js/rspack.config.js @@ -50,7 +50,6 @@ const common = ({ mode, disableRHC = false }) => { */ __BUILD_FLAG_KEYLESS_UI__: isDevelopment(mode), __BUILD_DISABLE_RHC__: JSON.stringify(disableRHC), - BUILD_ENABLE_NEW_COMPONENTS: JSON.stringify(process.env.BUILD_ENABLE_NEW_COMPONENTS), }), new rspack.EnvironmentPlugin({ CLERK_ENV: mode, diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 755e6e83f8d..d555e07225c 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -34,7 +34,6 @@ import type { InstanceType, JoinWaitlistParams, ListenerCallback, - LoadedClerk, NavigateOptions, OrganizationListProps, OrganizationProfileProps, @@ -68,7 +67,6 @@ import type { } from '@clerk/types'; import type { MountComponentRenderer } from '../ui/Components'; -import { UI } from '../ui/new'; import { ALLOWED_PROTOCOLS, buildURL, @@ -155,12 +153,7 @@ const defaultOptions: ClerkOptions = { signUpForceRedirectUrl: undefined, }; -function clerkIsLoaded(clerk: ClerkInterface): clerk is LoadedClerk { - return !!clerk.client; -} - export class Clerk implements ClerkInterface { - public __experimental_ui?: UI; public static mountComponentRenderer?: MountComponentRenderer; public static version: string = __PKG_VERSION__; @@ -353,16 +346,6 @@ export class Clerk implements ClerkInterface { } else { this.#loaded = await this.#loadInNonStandardBrowser(); } - - if (BUILD_ENABLE_NEW_COMPONENTS) { - if (clerkIsLoaded(this)) { - this.__experimental_ui = new UI({ - router: this.#options.__experimental_router, - clerk: this, - options: this.#options, - }); - } - } }; #isCombinedSignInOrUpFlow(): boolean { @@ -578,19 +561,15 @@ export class Clerk implements ClerkInterface { }; public mountSignIn = (node: HTMLDivElement, props?: SignInProps): void => { - if (props?.__experimental?.newComponents && this.__experimental_ui) { - this.__experimental_ui.mount('SignIn', node, props); - } else { - this.assertComponentsReady(this.#componentControls); - void this.#componentControls.ensureMounted({ preloadHint: 'SignIn' }).then(controls => - controls.mountComponent({ - name: 'SignIn', - appearanceKey: 'signIn', - node, - props, - }), - ); - } + this.assertComponentsReady(this.#componentControls); + void this.#componentControls.ensureMounted({ preloadHint: 'SignIn' }).then(controls => + controls.mountComponent({ + name: 'SignIn', + appearanceKey: 'signIn', + node, + props, + }), + ); this.telemetry?.record( eventPrebuiltComponentMounted('SignIn', { ...props, @@ -609,19 +588,15 @@ export class Clerk implements ClerkInterface { }; public mountSignUp = (node: HTMLDivElement, props?: SignUpProps): void => { - if (props?.__experimental?.newComponents && this.__experimental_ui) { - this.__experimental_ui.mount('SignUp', node, props); - } else { - this.assertComponentsReady(this.#componentControls); - void this.#componentControls.ensureMounted({ preloadHint: 'SignUp' }).then(controls => - controls.mountComponent({ - name: 'SignUp', - appearanceKey: 'signUp', - node, - props, - }), - ); - } + this.assertComponentsReady(this.#componentControls); + void this.#componentControls.ensureMounted({ preloadHint: 'SignUp' }).then(controls => + controls.mountComponent({ + name: 'SignUp', + appearanceKey: 'signUp', + node, + props, + }), + ); this.telemetry?.record(eventPrebuiltComponentMounted('SignUp', props)); }; diff --git a/packages/clerk-js/src/ui/new/index.tsx b/packages/clerk-js/src/ui/new/index.tsx deleted file mode 100644 index 3a8646928f3..00000000000 --- a/packages/clerk-js/src/ui/new/index.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import type { ClerkHostRouter } from '@clerk/shared/router'; -import { createDeferredPromise } from '@clerk/shared/utils'; -import type { ClerkOptions, LoadedClerk } from '@clerk/types'; - -import type { init } from './renderer'; -import type { ClerkNewComponents, ComponentDefinition } from './types'; - -function assertRouter(router: ClerkHostRouter | undefined): asserts router is ClerkHostRouter { - if (!router) { - throw new Error(`Clerk: Attempted to use functionality that requires the "router" option to be provided to Clerk.`); - } -} - -export class UI { - router?: ClerkHostRouter; - clerk: LoadedClerk; - options: ClerkOptions; - componentRegistry = new Map(); - - #rendererPromise?: ReturnType; - #renderer?: ReturnType; - - constructor({ - router, - clerk, - options, - }: { - router: ClerkHostRouter | undefined; - clerk: LoadedClerk; - options: ClerkOptions; - }) { - this.router = router; - this.clerk = clerk; - this.options = options; - - if (BUILD_ENABLE_NEW_COMPONENTS) { - // register components - this.register('SignIn', { - type: 'component', - load: () => - import(/* webpackChunkName: "rebuild--sign-in" */ '@clerk/ui/sign-in').then(({ SignIn }) => ({ - default: SignIn, - })), - }); - this.register('SignUp', { - type: 'component', - load: () => - import(/* webpackChunkName: "rebuild--sign-up" */ '@clerk/ui/sign-up').then(({ SignUp }) => ({ - default: SignUp, - })), - }); - } - } - - // Mount a component from the registry - mount(componentName: C, node: HTMLElement, props: ClerkNewComponents[C]): void { - const component = this.componentRegistry.get(componentName); - if (!component) { - throw new Error(`clerk/ui: Unable to find component definition for ${componentName}`); - } - - // immediately start loading the component - component.load(); - - this.renderer() - .then(() => { - this.#renderer?.mount(this.#renderer.createElementFromComponentDefinition(component), props, node); - }) - .catch(err => { - console.error(`clerk/ui: Error mounting component ${componentName}:`, err); - }); - } - - unmount(node: HTMLElement) { - this.#renderer?.unmount(node); - } - - // Registers a component for rendering later - register(componentName: string, componentDefinition: ComponentDefinition) { - this.componentRegistry.set(componentName, componentDefinition); - } - - renderer() { - if (this.#rendererPromise) { - return this.#rendererPromise.promise; - } - - this.#rendererPromise = createDeferredPromise(); - - import('./renderer').then(({ init, wrapperInit }) => { - assertRouter(this.router); - this.#renderer = init({ - wrapper: wrapperInit({ clerk: this.clerk, options: this.options, router: this.router }), - }); - this.#rendererPromise?.resolve(); - }); - - return this.#rendererPromise.promise; - } -} diff --git a/packages/clerk-js/src/ui/new/renderer.tsx b/packages/clerk-js/src/ui/new/renderer.tsx deleted file mode 100644 index 95358f25f39..00000000000 --- a/packages/clerk-js/src/ui/new/renderer.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { ClerkInstanceContext, OptionsContext } from '@clerk/shared/react'; -import type { ClerkHostRouter } from '@clerk/shared/router'; -import { ClerkHostRouterContext } from '@clerk/shared/router'; -import type { ClerkOptions, LoadedClerk } from '@clerk/types'; -import stylesheetURLOrContent from '@clerk/ui/styles.css'; -import type { ElementType, ReactNode } from 'react'; -import { createElement, lazy } from 'react'; -import { createPortal } from 'react-dom'; -import { createRoot } from 'react-dom/client'; - -import type { ComponentDefinition } from './types'; - -const ROOT_ELEMENT_ID = 'clerk-components-new'; - -export function wrapperInit({ - clerk, - options, - router, -}: { - clerk: LoadedClerk; - options: ClerkOptions; - router: ClerkHostRouter; -}) { - return function Wrapper({ children }: { children: ReactNode }) { - return ( - - - {children} - - - ); - }; -} - -// Initializes the react renderer -export function init({ wrapper }: { wrapper: ElementType }) { - const renderedComponents = new Map]>(); - let rootElement = document.getElementById(ROOT_ELEMENT_ID); - - if (!rootElement) { - rootElement = document.createElement('div'); - rootElement.setAttribute('id', 'clerk-components'); - document.body.appendChild(rootElement); - - // Just for completeness, we check to see if we've already added the stylesheet to the DOM. - const STYLESHEET_SIGIL = 'data-clerk-injected-styles'; - const existingStylesheet = document.querySelector(`[${STYLESHEET_SIGIL}]`); - if (!existingStylesheet) { - let stylesheet: HTMLLinkElement | HTMLStyleElement; - - if (stylesheetURLOrContent.endsWith('.css')) { - // stylesheetURLOrContent is a URL to a stylesheet - stylesheet = document.createElement('link'); - (stylesheet as HTMLLinkElement).href = stylesheetURLOrContent; - (stylesheet as HTMLLinkElement).rel = 'stylesheet'; - } else { - // stylesheetURLOrContent is CSS - stylesheet = document.createElement('style'); - stylesheet.textContent = stylesheetURLOrContent; - } - - stylesheet.setAttribute(STYLESHEET_SIGIL, ''); - // Add as first stylesheet so that application styles take precedence over our styles. - document.head.prepend(stylesheet); - } - } - - const root = createRoot(rootElement); - - // (re-)renders the render wrapper, rendering any components present in the `renderedComponents` map. - // React's render function retains state, so it's safe to call multiple times as additional components are mounted and unmounted. - function render() { - root.render( - createElement( - wrapper, - null, - Array.from(renderedComponents.entries()).map(([node, [element, props]]) => - createPortal(createElement(element, props), node), - ), - ), - ); - } - - function mount(element: ElementType, props: any, node: HTMLElement) { - renderedComponents.set(node, [element, props]); - render(); - } - - function unmount(node: HTMLElement) { - if (!renderedComponents.has(node)) { - return; - } - - renderedComponents.delete(node); - render(); - } - - function createElementFromComponentDefinition(componentDefinition: ComponentDefinition) { - return lazy(componentDefinition.load); - } - - return { - mount, - unmount, - createElementFromComponentDefinition, - }; -} diff --git a/packages/clerk-js/src/ui/new/types.ts b/packages/clerk-js/src/ui/new/types.ts deleted file mode 100644 index ef5a3281961..00000000000 --- a/packages/clerk-js/src/ui/new/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { SignInProps, SignUpProps } from '@clerk/types'; -import type { ComponentType } from 'react'; - -export interface ComponentDefinition { - type: 'component' | 'modal'; - load: () => Promise<{ default: ComponentType }>; -} - -export type ClerkNewComponents = { - SignIn: SignInProps; - SignUp: SignUpProps; -}; diff --git a/packages/clerk-js/turbo.json b/packages/clerk-js/turbo.json index ecd642c0f5b..2e9d62c5c8c 100644 --- a/packages/clerk-js/turbo.json +++ b/packages/clerk-js/turbo.json @@ -2,7 +2,6 @@ "extends": ["//"], "tasks": { "build": { - "env": ["BUILD_ENABLE_NEW_COMPONENTS"], "inputs": [ "*.d.ts", "headless/**", From ec9e3c774e472fe6efae7f56fbeda06f98f8f2e1 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Mon, 20 Jan 2025 15:31:22 -0600 Subject: [PATCH 2/3] Adds changeset --- .changeset/little-rivers-push.md | 5 +++++ packages/clerk-js/src/global.d.ts | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 .changeset/little-rivers-push.md diff --git a/.changeset/little-rivers-push.md b/.changeset/little-rivers-push.md new file mode 100644 index 00000000000..a5000eb1e39 --- /dev/null +++ b/.changeset/little-rivers-push.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Remove unused, experimental code for a new UI component rendering path. diff --git a/packages/clerk-js/src/global.d.ts b/packages/clerk-js/src/global.d.ts index 30bc32d54d1..98dd9b084a8 100644 --- a/packages/clerk-js/src/global.d.ts +++ b/packages/clerk-js/src/global.d.ts @@ -8,7 +8,6 @@ declare module '*.svg' { export default value; } -declare const BUILD_ENABLE_NEW_COMPONENTS: string; declare const __PKG_NAME__: string; declare const __PKG_VERSION__: string; declare const __DEV__: boolean; From 58213ee111377b6ca3beecb7350bfb2a1c55c679 Mon Sep 17 00:00:00 2001 From: Bryce Kalow Date: Mon, 20 Jan 2025 15:43:53 -0600 Subject: [PATCH 3/3] Removes experimental router option --- packages/types/src/clerk.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/types/src/clerk.ts b/packages/types/src/clerk.ts index 41bf0282eed..f82b4e669b8 100644 --- a/packages/types/src/clerk.ts +++ b/packages/types/src/clerk.ts @@ -31,7 +31,6 @@ import type { SignUpFallbackRedirectUrl, SignUpForceRedirectUrl, } from './redirects'; -import type { ClerkHostRouter } from './router'; import type { ActiveSessionResource } from './session'; import type { SessionVerificationLevel } from './sessionVerification'; import type { SignInResource } from './signIn'; @@ -776,11 +775,6 @@ export type ClerkOptions = ClerkOptionsNavigation & * After a developer has claimed their instance created by Keyless mode, they can use this URL to find their instance's keys */ __internal_copyInstanceKeysUrl?: string; - - /** - * [EXPERIMENTAL] Provide the underlying host router, required for the new experimental UI components. - */ - __experimental_router?: ClerkHostRouter; }; export interface NavigateOptions {