From 3dc4ced5ba6e31ba51860c1a6126861d7303211e Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 10:26:52 -0400 Subject: [PATCH 1/9] refactor(clerk-js,shared): Expand ApplicationLogo usage for oAuth logo --- .../components/OAuthConsent/OAuthConsent.tsx | 64 +++++++++---------- .../src/ui/elements/ApplicationLogo.tsx | 55 ++++++++++++---- packages/shared/src/url.ts | 4 ++ 3 files changed, 79 insertions(+), 44 deletions(-) diff --git a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx index 6841e39dc2a..4213c5e2c29 100644 --- a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx +++ b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx @@ -1,10 +1,10 @@ import { useUser } from '@clerk/shared/react'; +import type { ComponentProps } from 'react'; import { useState } from 'react'; import { useEnvironment, useOAuthConsentContext } from '@/ui/contexts'; import { Box, Button, Flex, Flow, Grid, Icon, Text } from '@/ui/customizables'; import { ApplicationLogo } from '@/ui/elements/ApplicationLogo'; -import { Avatar } from '@/ui/elements/Avatar'; import { Card } from '@/ui/elements/Card'; import { withCardStateProvider } from '@/ui/elements/contexts'; import { Header } from '@/ui/elements/Header'; @@ -42,13 +42,13 @@ export function OAuthConsentInternal() { {/* both have avatars */} {oAuthApplicationLogoUrl && logoImageUrl && ( - t.space.$12} - rounded={false} - /> + + + - + + + )} {/* only OAuth app has an avatar */} @@ -59,11 +59,7 @@ export function OAuthConsentInternal() { position: 'relative', }} > - t.space.$12} - rounded={false} - /> + ({ @@ -77,31 +73,21 @@ export function OAuthConsentInternal() { )} {/* only Clerk application has an avatar */} {!oAuthApplicationLogoUrl && logoImageUrl && ( - ({ - marginBlockEnd: t.space.$6, - })} - > - + + + + - - + + + + )} {/* no avatars */} {!oAuthApplicationLogoUrl && !logoImageUrl && ( - ({ - marginBlockEnd: t.space.$6, - })} - > + - + )} ) { + return ( + + {children} + + ); +} + function ConnectionIcon({ size = 'md', sx }: { size?: 'sm' | 'md'; sx?: ThemableCssProp }) { const scale: ThemableCssProp = t => { const value = size === 'sm' ? t.space.$6 : t.space.$12; diff --git a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx index 68f8905f267..decdfa10976 100644 --- a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx +++ b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx @@ -1,8 +1,11 @@ +import { isExternalUrl } from '@clerk/shared/url'; import React from 'react'; import { useEnvironment } from '../contexts'; import { descriptors, Flex, Image, useAppearance } from '../customizables'; -import type { PropsOfComponent } from '../styledSystem'; +import { Link } from '../primitives'; +import type { InternalTheme, PropsOfComponent } from '../styledSystem'; +import { common } from '../styledSystem'; import { RouterLink } from './RouterLink'; const getContainerHeightForImageRatio = (imageRef: React.RefObject, width: string) => { @@ -21,15 +24,24 @@ const getContainerHeightForImageRatio = (imageRef: React.RefObject; +type ApplicationLogoProps = PropsOfComponent & { + /** + * The URL of the image to display. + */ + src?: string; + /** + * The URL to navigate to when the logo is clicked. + */ + href?: string; +}; export const ApplicationLogo = (props: ApplicationLogoProps) => { const imageRef = React.useRef(null); const [loaded, setLoaded] = React.useState(false); const { logoImageUrl, applicationName, homeUrl } = useEnvironment().displayConfig; const { parsedLayout } = useAppearance(); - const imageSrc = parsedLayout.logoImageUrl || logoImageUrl; - const logoUrl = parsedLayout.logoLinkUrl || homeUrl; + const imageSrc = props.src || parsedLayout.logoImageUrl || logoImageUrl; + const logoUrl = props.href || parsedLayout.logoLinkUrl || homeUrl; if (!imageSrc) { return null; @@ -65,14 +77,33 @@ export const ApplicationLogo = (props: ApplicationLogoProps) => { ]} > {logoUrl ? ( - - {image} - + isExternalUrl(logoUrl) ? ( + ({ + '&:focus': { + ...common.focusRing(theme), + outline: 'none', + }, + })} + > + {image} + + ) : ( + ({ + justifyContent: 'center', + '&:focus': { + ...common.focusRing(theme), + outline: 'none', + }, + })} + to={logoUrl} + > + {image} + + ) ) : ( image )} diff --git a/packages/shared/src/url.ts b/packages/shared/src/url.ts index 651d0453e75..a754c8c075d 100644 --- a/packages/shared/src/url.ts +++ b/packages/shared/src/url.ts @@ -177,3 +177,7 @@ export function joinURL(base: string, ...input: string[]): string { // Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/; export const isAbsoluteUrl = (url: string) => ABSOLUTE_URL_REGEX.test(url); + +export const isExternalUrl = (url: string) => { + return isAbsoluteUrl(url) && !url.startsWith(window.location.origin); +}; From fcd25b4f17de68755637e7f5856472737e24333b Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 10:36:13 -0400 Subject: [PATCH 2/9] add focusRing variant --- .../src/ui/elements/ApplicationLogo.tsx | 18 +++--------------- packages/clerk-js/src/ui/primitives/Link.tsx | 9 +++++++++ 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx index decdfa10976..47033712a03 100644 --- a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx +++ b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx @@ -4,8 +4,7 @@ import React from 'react'; import { useEnvironment } from '../contexts'; import { descriptors, Flex, Image, useAppearance } from '../customizables'; import { Link } from '../primitives'; -import type { InternalTheme, PropsOfComponent } from '../styledSystem'; -import { common } from '../styledSystem'; +import type { PropsOfComponent } from '../styledSystem'; import { RouterLink } from './RouterLink'; const getContainerHeightForImageRatio = (imageRef: React.RefObject, width: string) => { @@ -81,24 +80,13 @@ export const ApplicationLogo = (props: ApplicationLogoProps) => { ({ - '&:focus': { - ...common.focusRing(theme), - outline: 'none', - }, - })} + focusRing > {image} ) : ( ({ - justifyContent: 'center', - '&:focus': { - ...common.focusRing(theme), - outline: 'none', - }, - })} + focusRing to={logoUrl} > {image} diff --git a/packages/clerk-js/src/ui/primitives/Link.tsx b/packages/clerk-js/src/ui/primitives/Link.tsx index 136ef88fa1a..b57e89caef2 100644 --- a/packages/clerk-js/src/ui/primitives/Link.tsx +++ b/packages/clerk-js/src/ui/primitives/Link.tsx @@ -33,10 +33,19 @@ const { applyVariants, filterProps } = createVariants(theme => ({ }, inherit: { color: 'inherit' }, }, + focusRing: { + true: { + '&:focus': { + outline: 'none', + ...common.focusRing(theme), + }, + }, + }, }, defaultVariants: { colorScheme: 'primary', variant: 'body', + focusRing: false, }, })); From 3344db6f2c7599fd6f20f794726dd544340a3eb1 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 10:46:21 -0400 Subject: [PATCH 3/9] add alt text --- .../components/OAuthConsent/OAuthConsent.tsx | 20 +++++++++++++++---- .../src/ui/elements/ApplicationLogo.tsx | 4 ++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx index 4213c5e2c29..e9f189b4483 100644 --- a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx +++ b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx @@ -17,8 +17,14 @@ import { common } from '@/ui/styledSystem'; import { colors } from '@/ui/utils/colors'; export function OAuthConsentInternal() { - const { scopes, oAuthApplicationName, oAuthApplicationLogoUrl, redirectUrl, onDeny, onAllow } = - useOAuthConsentContext(); + const { + scopes, + oAuthApplicationName, + oAuthApplicationLogoUrl = 'https://img.clerk.com/eyJ0eXBlIjoicHJveHkiLCJzcmMiOiJodHRwczovL2ltYWdlcy5jbGVyay5kZXYvdXBsb2FkZWQvaW1nXzMxOHVMSERjc0hTNXNaWlF0MlFEeWxpMER0RyJ9?width=400', + redirectUrl, + onDeny, + onAllow, + } = useOAuthConsentContext(); const { user } = useUser(); const { applicationName, logoImageUrl } = useEnvironment().displayConfig; const [isUriModalOpen, setIsUriModalOpen] = useState(false); @@ -43,7 +49,10 @@ export function OAuthConsentInternal() { {oAuthApplicationLogoUrl && logoImageUrl && ( - + @@ -59,7 +68,10 @@ export function OAuthConsentInternal() { position: 'relative', }} > - + ({ diff --git a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx index 47033712a03..a511335cfd7 100644 --- a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx +++ b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx @@ -28,6 +28,10 @@ type ApplicationLogoProps = PropsOfComponent & { * The URL of the image to display. */ src?: string; + /** + * The alt text for the image. + */ + alt?: string; /** * The URL to navigate to when the logo is clicked. */ From 84600922be7eec3addee7f9afd6ef8c0edd4b651 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 10:47:09 -0400 Subject: [PATCH 4/9] refactor sx --- .../clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx index e9f189b4483..b44a9f96725 100644 --- a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx +++ b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx @@ -322,10 +322,7 @@ function ConnectionItem({ children, ...props }: ComponentProps) { return ( {children} From 8137a405da92a13cf1b1d244a00051ddc00d57c8 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 10:53:15 -0400 Subject: [PATCH 5/9] avoid external linking logic --- .../src/ui/elements/ApplicationLogo.tsx | 24 +++++-------------- packages/shared/src/url.ts | 4 ---- 2 files changed, 6 insertions(+), 22 deletions(-) diff --git a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx index a511335cfd7..78913ca4e9f 100644 --- a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx +++ b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx @@ -1,9 +1,7 @@ -import { isExternalUrl } from '@clerk/shared/url'; import React from 'react'; import { useEnvironment } from '../contexts'; import { descriptors, Flex, Image, useAppearance } from '../customizables'; -import { Link } from '../primitives'; import type { PropsOfComponent } from '../styledSystem'; import { RouterLink } from './RouterLink'; @@ -80,22 +78,12 @@ export const ApplicationLogo = (props: ApplicationLogoProps) => { ]} > {logoUrl ? ( - isExternalUrl(logoUrl) ? ( - - {image} - - ) : ( - - {image} - - ) + + {image} + ) : ( image )} diff --git a/packages/shared/src/url.ts b/packages/shared/src/url.ts index a754c8c075d..651d0453e75 100644 --- a/packages/shared/src/url.ts +++ b/packages/shared/src/url.ts @@ -177,7 +177,3 @@ export function joinURL(base: string, ...input: string[]): string { // Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 const ABSOLUTE_URL_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*?:/; export const isAbsoluteUrl = (url: string) => ABSOLUTE_URL_REGEX.test(url); - -export const isExternalUrl = (url: string) => { - return isAbsoluteUrl(url) && !url.startsWith(window.location.origin); -}; From e734d9d77a9989cbbd4f751cbcc8ba661fe922e7 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 10:55:04 -0400 Subject: [PATCH 6/9] add changeset --- .changeset/chilly-ravens-cover.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chilly-ravens-cover.md diff --git a/.changeset/chilly-ravens-cover.md b/.changeset/chilly-ravens-cover.md new file mode 100644 index 00000000000..f76a02f0b72 --- /dev/null +++ b/.changeset/chilly-ravens-cover.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Refactor ApplicationLogo rendering logic to account for oAuth logos within OAuthConsent component. From 5d9034db4ffe9cc66c733a5967e08e2dc5ef5f9d Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 11:55:40 -0400 Subject: [PATCH 7/9] fix prop spread --- packages/clerk-js/bundlewatch.config.json | 2 +- .../clerk-js/src/ui/elements/ApplicationLogo.tsx | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/clerk-js/bundlewatch.config.json b/packages/clerk-js/bundlewatch.config.json index 55893738a3c..ba097e2b1b8 100644 --- a/packages/clerk-js/bundlewatch.config.json +++ b/packages/clerk-js/bundlewatch.config.json @@ -1,6 +1,6 @@ { "files": [ - { "path": "./dist/clerk.js", "maxSize": "621KB" }, + { "path": "./dist/clerk.js", "maxSize": "621.1KB" }, { "path": "./dist/clerk.browser.js", "maxSize": "75KB" }, { "path": "./dist/clerk.legacy.browser.js", "maxSize": "117KB" }, { "path": "./dist/clerk.headless*.js", "maxSize": "57KB" }, diff --git a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx index 78913ca4e9f..f9125511ff3 100644 --- a/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx +++ b/packages/clerk-js/src/ui/elements/ApplicationLogo.tsx @@ -21,7 +21,7 @@ const getContainerHeightForImageRatio = (imageRef: React.RefObject & { +export type ApplicationLogoProps = PropsOfComponent & { /** * The URL of the image to display. */ @@ -36,13 +36,15 @@ type ApplicationLogoProps = PropsOfComponent & { href?: string; }; -export const ApplicationLogo = (props: ApplicationLogoProps) => { +export const ApplicationLogo: React.FC = (props: ApplicationLogoProps): JSX.Element | null => { + const { src, alt, href, sx, ...rest } = props; const imageRef = React.useRef(null); const [loaded, setLoaded] = React.useState(false); const { logoImageUrl, applicationName, homeUrl } = useEnvironment().displayConfig; const { parsedLayout } = useAppearance(); - const imageSrc = props.src || parsedLayout.logoImageUrl || logoImageUrl; - const logoUrl = props.href || parsedLayout.logoLinkUrl || homeUrl; + const imageSrc = src || parsedLayout.logoImageUrl || logoImageUrl; + const imageAlt = alt || applicationName; + const logoUrl = href || parsedLayout.logoLinkUrl || homeUrl; if (!imageSrc) { return null; @@ -52,7 +54,7 @@ export const ApplicationLogo = (props: ApplicationLogoProps) => { {applicationName} setLoaded(true)} @@ -68,13 +70,13 @@ export const ApplicationLogo = (props: ApplicationLogoProps) => { return ( ({ height: getContainerHeightForImageRatio(imageRef, theme.sizes.$6), justifyContent: 'center', }), - props.sx, + sx, ]} > {logoUrl ? ( From 5b6a8238cd29b863ff7cc0d73d39b88c45263792 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 13:02:01 -0400 Subject: [PATCH 8/9] remove debugging --- .../src/ui/components/OAuthConsent/OAuthConsent.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx index b44a9f96725..4aad794f3d8 100644 --- a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx +++ b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx @@ -17,14 +17,8 @@ import { common } from '@/ui/styledSystem'; import { colors } from '@/ui/utils/colors'; export function OAuthConsentInternal() { - const { - scopes, - oAuthApplicationName, - oAuthApplicationLogoUrl = 'https://img.clerk.com/eyJ0eXBlIjoicHJveHkiLCJzcmMiOiJodHRwczovL2ltYWdlcy5jbGVyay5kZXYvdXBsb2FkZWQvaW1nXzMxOHVMSERjc0hTNXNaWlF0MlFEeWxpMER0RyJ9?width=400', - redirectUrl, - onDeny, - onAllow, - } = useOAuthConsentContext(); + const { scopes, oAuthApplicationName, oAuthApplicationLogoUrl, redirectUrl, onDeny, onAllow } = + useOAuthConsentContext(); const { user } = useUser(); const { applicationName, logoImageUrl } = useEnvironment().displayConfig; const [isUriModalOpen, setIsUriModalOpen] = useState(false); From ec7c93b6c9b4bc00df4a86eed84de824e4d836ff Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Mon, 11 Aug 2025 13:08:16 -0400 Subject: [PATCH 9/9] destructure sx --- .../clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx index 4aad794f3d8..dc7a55fac4c 100644 --- a/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx +++ b/packages/clerk-js/src/ui/components/OAuthConsent/OAuthConsent.tsx @@ -312,11 +312,11 @@ function ConnectionHeader({ children }: { children: React.ReactNode }) { ); } -function ConnectionItem({ children, ...props }: ComponentProps) { +function ConnectionItem({ children, sx, ...props }: ComponentProps) { return ( {children}