diff --git a/.changeset/lucky-bees-whisper.md b/.changeset/lucky-bees-whisper.md new file mode 100644 index 00000000000..ae9d9dea4c3 --- /dev/null +++ b/.changeset/lucky-bees-whisper.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Correct the HTML structure of the UI components to ensure validity diff --git a/packages/clerk-js/src/ui/common/NotificationCountBadge.tsx b/packages/clerk-js/src/ui/common/NotificationCountBadge.tsx index d562feebe89..271ae6c62ea 100644 --- a/packages/clerk-js/src/ui/common/NotificationCountBadge.tsx +++ b/packages/clerk-js/src/ui/common/NotificationCountBadge.tsx @@ -35,6 +35,7 @@ export const NotificationCountBadge = (props: NotificationCountBadgeProps) => { ({ marginLeft: t.space.$1x5, diff --git a/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx b/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx index 973b112e1d7..73b92f0a46e 100644 --- a/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationList/OrganizationListPage.tsx @@ -180,25 +180,25 @@ const OrganizationListPageList = (props: { onCreateOrganizationClick: () => void })} {(hasNextPage || isLoading) && } + + ({ + borderTopWidth: t.borderWidths.$normal, + borderTopStyle: t.borderStyles.$solid, + borderTopColor: t.colors.$neutralAlpha100, + padding: `${t.space.$5} ${t.space.$5}`, + })} + iconSx={t => ({ + width: t.sizes.$9, + height: t.sizes.$6, + })} + /> - - ({ - borderTopWidth: t.borderWidths.$normal, - borderTopStyle: t.borderStyles.$solid, - borderTopColor: t.colors.$neutralAlpha100, - padding: `${t.space.$5} ${t.space.$5}`, - })} - iconSx={t => ({ - width: t.sizes.$9, - height: t.sizes.$6, - })} - /> ); diff --git a/packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcher.tsx b/packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcher.tsx index b35a75414af..bf29de404ab 100644 --- a/packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcher.tsx +++ b/packages/clerk-js/src/ui/components/OrganizationSwitcher/OrganizationSwitcher.tsx @@ -26,7 +26,8 @@ const _OrganizationSwitcher = withFloatingTree(() => { ref={reference} onClick={toggle} isOpen={isOpen} - aria-controls={switcherButtonMenuId} + aria-controls={isOpen ? switcherButtonMenuId : undefined} + aria-expanded={isOpen} /> { ref={reference} onClick={toggle} isOpen={isOpen} - aria-controls={userButtonMenuId} + aria-controls={isOpen ? userButtonMenuId : undefined} + aria-expanded={isOpen} /> ({ diff --git a/packages/clerk-js/src/ui/components/UserButton/UserButtonTrigger.tsx b/packages/clerk-js/src/ui/components/UserButton/UserButtonTrigger.tsx index 40defd3dfe9..eff7c9251c3 100644 --- a/packages/clerk-js/src/ui/components/UserButton/UserButtonTrigger.tsx +++ b/packages/clerk-js/src/ui/components/UserButton/UserButtonTrigger.tsx @@ -32,6 +32,7 @@ export const UserButtonTrigger = withAvatarShimmer( elementDescriptor={descriptors.userButtonBox} isOpen={props.isOpen} align='center' + as='span' gap={2} > diff --git a/packages/clerk-js/src/ui/components/UserProfile/ConnectedAccountsSection.tsx b/packages/clerk-js/src/ui/components/UserProfile/ConnectedAccountsSection.tsx index 1ce07a35a19..7dc30f5468a 100644 --- a/packages/clerk-js/src/ui/components/UserProfile/ConnectedAccountsSection.tsx +++ b/packages/clerk-js/src/ui/components/UserProfile/ConnectedAccountsSection.tsx @@ -75,7 +75,6 @@ export const ConnectedAccountsSection = withCardStateProvider(() => { /> diff --git a/packages/clerk-js/src/ui/components/UserProfile/EmailsSection.tsx b/packages/clerk-js/src/ui/components/UserProfile/EmailsSection.tsx index f248ef3da1e..f061a467c90 100644 --- a/packages/clerk-js/src/ui/components/UserProfile/EmailsSection.tsx +++ b/packages/clerk-js/src/ui/components/UserProfile/EmailsSection.tsx @@ -52,10 +52,7 @@ export const EmailsSection = () => { id='emailAddresses' hoverable > - ({ overflow: 'hidden', gap: t.space.$1 })} - > + ({ overflow: 'hidden', gap: t.space.$1 })}> ({ color: t.colors.$colorText })} truncate diff --git a/packages/clerk-js/src/ui/components/UserProfile/EnterpriseAccountsSection.tsx b/packages/clerk-js/src/ui/components/UserProfile/EnterpriseAccountsSection.tsx index 9ea9e0215b7..fbf5ad08b3e 100644 --- a/packages/clerk-js/src/ui/components/UserProfile/EnterpriseAccountsSection.tsx +++ b/packages/clerk-js/src/ui/components/UserProfile/EnterpriseAccountsSection.tsx @@ -40,7 +40,6 @@ export const EnterpriseAccountsSection = () => { /> diff --git a/packages/clerk-js/src/ui/components/UserProfile/Web3Section.tsx b/packages/clerk-js/src/ui/components/UserProfile/Web3Section.tsx index c23c316b76f..e013a0031ca 100644 --- a/packages/clerk-js/src/ui/components/UserProfile/Web3Section.tsx +++ b/packages/clerk-js/src/ui/components/UserProfile/Web3Section.tsx @@ -57,7 +57,6 @@ export const Web3Section = withCardStateProvider(() => { )} diff --git a/packages/clerk-js/src/ui/elements/Actions.tsx b/packages/clerk-js/src/ui/elements/Actions.tsx index e6a4f9b6a49..cdda572b774 100644 --- a/packages/clerk-js/src/ui/elements/Actions.tsx +++ b/packages/clerk-js/src/ui/elements/Actions.tsx @@ -95,6 +95,7 @@ export const ExtraSmallAction = (props: Omit) => { elementDescriptor={iconBoxElementDescriptor} elementId={iconBoxElementId} justify='center' + as='span' > {status.isLoading ? ( { elementDescriptor={iconBoxElementDescriptor} elementId={iconBoxElementId} justify='center' + as='span' sx={[t => ({ flex: `0 0 ${t.sizes.$9}`, gap: t.space.$2, alignItems: 'center' }), iconBoxSx]} > {status.isLoading ? ( diff --git a/packages/clerk-js/src/ui/elements/ArrowBlockButton.tsx b/packages/clerk-js/src/ui/elements/ArrowBlockButton.tsx index 4c7543c622a..05bcfecd09b 100644 --- a/packages/clerk-js/src/ui/elements/ArrowBlockButton.tsx +++ b/packages/clerk-js/src/ui/elements/ArrowBlockButton.tsx @@ -103,6 +103,7 @@ export const ArrowBlockButton = React.forwardRef { title={title} alt={title} src={imageUrl || ''} - width='100%' - height='100%' - sx={{ objectFit: 'cover' }} + sx={{ objectFit: 'cover', width: '100%', height: '100%' }} onError={() => setError(true)} size={imageFetchSize} /> @@ -51,6 +49,7 @@ export const Avatar = (props: AvatarProps) => { // TODO: Revise size handling. Do we need to be this dynamic or should we use the theme instead? return ( ({ @@ -73,6 +72,7 @@ export const Avatar = (props: AvatarProps) => { * The ":after" selector is responsible for the border shimmer animation. */} ({ overflow: 'hidden', background: t.colors.$colorShimmer, diff --git a/packages/clerk-js/src/ui/elements/OrganizationPreview.tsx b/packages/clerk-js/src/ui/elements/OrganizationPreview.tsx index 974a7cbde8f..43e97d32f1c 100644 --- a/packages/clerk-js/src/ui/elements/OrganizationPreview.tsx +++ b/packages/clerk-js/src/ui/elements/OrganizationPreview.tsx @@ -52,6 +52,7 @@ export const OrganizationPreview = (props: OrganizationPreviewProps) => { elementId={descriptors.organizationPreview.setId(elementId)} gap={3} align='center' + as='span' sx={[{ minWidth: '0' }, sx]} {...rest} > @@ -59,6 +60,7 @@ export const OrganizationPreview = (props: OrganizationPreviewProps) => { elementDescriptor={descriptors.organizationPreviewAvatarContainer} elementId={descriptors.organizationPreviewAvatarContainer.setId(elementId)} justify='center' + as='span' sx={{ position: 'relative' }} > { elementId={descriptors.organizationPreviewTextContainer.setId(elementId)} direction='col' justify='center' + as='span' sx={{ minWidth: '0px', textAlign: 'left' }} > @@ -92,6 +96,7 @@ export const OrganizationPreview = (props: OrganizationPreviewProps) => { elementDescriptor={descriptors.organizationPreviewSecondaryIdentifier} elementId={descriptors.organizationPreviewSecondaryIdentifier.setId(elementId)} localizationKey={localizeCustomRole(membership?.role) || unlocalizedRoleLabel} + as='span' truncate /> )} diff --git a/packages/clerk-js/src/ui/elements/PhoneInput/PhoneInput.tsx b/packages/clerk-js/src/ui/elements/PhoneInput/PhoneInput.tsx index ccaa8f896ce..754c5a9ca7b 100644 --- a/packages/clerk-js/src/ui/elements/PhoneInput/PhoneInput.tsx +++ b/packages/clerk-js/src/ui/elements/PhoneInput/PhoneInput.tsx @@ -135,6 +135,7 @@ const PhoneInputBase = forwardRef ({ opacity: t.opacity.$inactive })}>{placeholder} + ({ opacity: t.opacity.$inactive })} + > + {placeholder} + ); } diff --git a/packages/clerk-js/src/ui/elements/SocialButtons.tsx b/packages/clerk-js/src/ui/elements/SocialButtons.tsx index 8ef60940551..7163d4dbc32 100644 --- a/packages/clerk-js/src/ui/elements/SocialButtons.tsx +++ b/packages/clerk-js/src/ui/elements/SocialButtons.tsx @@ -207,6 +207,7 @@ const SocialButtonBlock = (props: SocialButtonProps): JSX.Element => { { ({ borderBottomStyle: t.borderStyles.$solid, diff --git a/packages/clerk-js/src/ui/elements/UserPreview.tsx b/packages/clerk-js/src/ui/elements/UserPreview.tsx index b1c516d1fc0..9c7ca839088 100644 --- a/packages/clerk-js/src/ui/elements/UserPreview.tsx +++ b/packages/clerk-js/src/ui/elements/UserPreview.tsx @@ -85,6 +85,7 @@ export const UserPreview = (props: UserPreviewProps) => { elementDescriptor={descriptors.userPreview} elementId={descriptors.userPreview.setId(elementId)} align='center' + as='span' sx={[t => ({ minWidth: '0px', width: 'fit-content', gap: t.space.$4 }), sx]} {...rest} > @@ -95,6 +96,7 @@ export const UserPreview = (props: UserPreviewProps) => { elementDescriptor={descriptors.userPreviewAvatarContainer} elementId={descriptors.userPreviewAvatarContainer.setId(elementId)} justify='center' + as='span' sx={{ position: 'relative' }} > { {icon} @@ -125,6 +128,7 @@ export const UserPreview = (props: UserPreviewProps) => { elementDescriptor={descriptors.userPreviewAvatarContainer} elementId={descriptors.userPreviewAvatarContainer.setId(elementId)} justify='center' + as='span' sx={t => ({ height: getAvatarSizes(t), })} @@ -137,12 +141,14 @@ export const UserPreview = (props: UserPreviewProps) => { elementId={descriptors.userPreviewTextContainer.setId(elementId)} direction='col' justify='center' + as='span' sx={{ minWidth: '0px', textAlign: 'left' }} > ({ display: 'flex', gap: theme.sizes.$1, alignItems: 'center' }), mainIdentifierSx]} > {previewTitle && ( @@ -163,6 +169,7 @@ export const UserPreview = (props: UserPreviewProps) => { elementDescriptor={descriptors.userPreviewSecondaryIdentifier} elementId={descriptors.userPreviewSecondaryIdentifier.setId(elementId)} truncate + as='span' localizationKey={subtitle || identifier} /> )} diff --git a/packages/clerk-js/src/ui/elements/__tests__/PlainInput.test.tsx b/packages/clerk-js/src/ui/elements/__tests__/PlainInput.test.tsx index 219e4867d3a..67f2aff11f7 100644 --- a/packages/clerk-js/src/ui/elements/__tests__/PlainInput.test.tsx +++ b/packages/clerk-js/src/ui/elements/__tests__/PlainInput.test.tsx @@ -47,7 +47,6 @@ describe('PlainInput', () => { expect(getByLabelText('some label')).not.toHaveAttribute('disabled'); expect(getByLabelText('some label')).not.toHaveAttribute('required'); expect(getByLabelText('some label')).toHaveAttribute('aria-invalid', 'false'); - expect(getByLabelText('some label')).toHaveAttribute('aria-describedby', ''); expect(getByLabelText('some label')).toHaveAttribute('aria-required', 'false'); expect(getByLabelText('some label')).toHaveAttribute('aria-disabled', 'false'); }); diff --git a/packages/clerk-js/src/ui/primitives/Input.tsx b/packages/clerk-js/src/ui/primitives/Input.tsx index 36978317e90..3c005475a07 100644 --- a/packages/clerk-js/src/ui/primitives/Input.tsx +++ b/packages/clerk-js/src/ui/primitives/Input.tsx @@ -95,7 +95,7 @@ export const Input = React.forwardRef((props, ref) required={_required} id={props.id || fieldControlProps.id} aria-invalid={_hasError} - aria-describedby={errorMessageId} + aria-describedby={errorMessageId ? errorMessageId : undefined} aria-required={_required} aria-disabled={_disabled} data-feedback={feedbackType}