diff --git a/.changeset/device-code-input-overflow.md b/.changeset/device-code-input-overflow.md
new file mode 100644
index 00000000000..fae703e6229
--- /dev/null
+++ b/.changeset/device-code-input-overflow.md
@@ -0,0 +1,5 @@
+---
+'@clerk/ui': patch
+---
+
+Fix the `` code input overflowing the card when the card is not flush.
diff --git a/packages/clerk-js/sandbox/app.ts b/packages/clerk-js/sandbox/app.ts
index 682f9b2f53e..11bdbbe370a 100644
--- a/packages/clerk-js/sandbox/app.ts
+++ b/packages/clerk-js/sandbox/app.ts
@@ -35,6 +35,7 @@ const AVAILABLE_COMPONENTS = [
'apiKeys',
'configureSSO',
'oauthConsent',
+ 'oauthDeviceVerification',
'taskChooseOrganization',
'taskResetPassword',
'taskSetupMFA',
@@ -154,6 +155,7 @@ const componentControls: Record = {
apiKeys: buildComponentControls('apiKeys'),
configureSSO: buildComponentControls('configureSSO'),
oauthConsent: buildComponentControls('oauthConsent'),
+ oauthDeviceVerification: buildComponentControls('oauthDeviceVerification'),
taskChooseOrganization: buildComponentControls('taskChooseOrganization'),
taskResetPassword: buildComponentControls('taskResetPassword'),
taskSetupMFA: buildComponentControls('taskSetupMFA'),
@@ -425,6 +427,10 @@ void (async () => {
'/pricing-table': { mount: 'mountPricingTable', component: 'pricingTable' },
'/api-keys': { mount: 'mountAPIKeys', component: 'apiKeys' },
'/configure-sso': { mount: '__internal_mountConfigureSSO', component: 'configureSSO' },
+ '/oauth-device-verification': {
+ mount: '__internal_mountOAuthDeviceVerification',
+ component: 'oauthDeviceVerification',
+ },
'/task-choose-organization': {
mount: 'mountTaskChooseOrganization',
component: 'taskChooseOrganization',
diff --git a/packages/clerk-js/sandbox/template.html b/packages/clerk-js/sandbox/template.html
index f59c231dceb..e7c5d8d344e 100644
--- a/packages/clerk-js/sandbox/template.html
+++ b/packages/clerk-js/sandbox/template.html
@@ -259,6 +259,11 @@
label="OAuth Consent"
component=""
>
+
({ gap: t.space.$1x5 })}
hasError={hasError}
>
{slots.map((slot, index) => (
@@ -27,6 +27,7 @@ function CodeGroup({ slots, hasError }: { slots: SlotProps[]; hasError: boolean
key={index}
elementDescriptor={descriptors.otpCodeFieldInput}
hasError={hasError}
+ sx={t => ({ width: t.space.$8, height: t.space.$8 })}
{...slot}
/>
))}
@@ -70,7 +71,7 @@ export function OAuthDeviceVerificationCodeInput({ control }: OAuthDeviceVerific
& { isSuccessfullyFilled?: boolean },
) {
const { isSuccessfullyFilled, ...otpProps } = props;
- const { char, hasFakeCaret, isActive, placeholderChar, ...rest } = otpProps;
+ const { char, hasFakeCaret, isActive, placeholderChar, sx, ...rest } = otpProps;
return (
({
- textAlign: 'center',
- ...common.textVariants(t).h2,
- padding: `${t.space.$0x5} 0`,
- boxSizing: 'border-box',
- display: 'flex',
- position: 'relative',
- alignItems: 'center',
- justifyContent: 'center',
- height: t.space.$10,
- width: t.space.$10,
- color: t.colors.$colorInputForeground,
- borderWidth: t.borderWidths.$normal,
- borderRadius: t.radii.$md,
- ...(isSuccessfullyFilled ? { borderColor: t.colors.$success500 } : common.borderColor(t, props)),
- backgroundColor: 'unset',
- [mqu.sm]: {
- height: t.space.$8,
- width: t.space.$8,
- },
- })}
+ sx={[
+ t => ({
+ textAlign: 'center',
+ ...common.textVariants(t).h2,
+ padding: `${t.space.$0x5} 0`,
+ boxSizing: 'border-box',
+ display: 'flex',
+ position: 'relative',
+ alignItems: 'center',
+ justifyContent: 'center',
+ height: t.space.$10,
+ width: t.space.$10,
+ color: t.colors.$colorInputForeground,
+ borderWidth: t.borderWidths.$normal,
+ borderRadius: t.radii.$md,
+ ...(isSuccessfullyFilled ? { borderColor: t.colors.$success500 } : common.borderColor(t, props)),
+ backgroundColor: 'unset',
+ [mqu.sm]: {
+ height: t.space.$8,
+ width: t.space.$8,
+ },
+ }),
+ sx,
+ ]}
>
{char !== null && {char}
}
{hasFakeCaret && }
diff --git a/packages/ui/src/elements/__tests__/CodeControl.test.tsx b/packages/ui/src/elements/__tests__/CodeControl.test.tsx
index 2ffbbf6d0ca..ae3f994bbf8 100644
--- a/packages/ui/src/elements/__tests__/CodeControl.test.tsx
+++ b/packages/ui/src/elements/__tests__/CodeControl.test.tsx
@@ -6,7 +6,7 @@ import { describe, expect, it, vi } from 'vitest';
import { bindCreateFixtures } from '@/test/create-fixtures';
-import { OTPCodeControl, OTPRoot, useFieldOTP } from '../CodeControl';
+import { OTPCodeControl, OTPInputSlot, OTPRoot, useFieldOTP } from '../CodeControl';
import { withCardStateProvider } from '../contexts';
const { createFixtures } = bindCreateFixtures('UserProfile');
@@ -51,6 +51,25 @@ const typeCode = async (input: HTMLElement, user: UserEvent, code = '123456') =>
};
describe('CodeControl', () => {
+ describe('OTPInputSlot', () => {
+ it('allows its dimensions to be overridden', async () => {
+ const { wrapper } = await createFixtures();
+
+ const { getByTestId } = render(
+ ,
+ { wrapper },
+ );
+
+ expect(getByTestId(testId)).toHaveStyle({ width: '2rem', height: '2rem' });
+ });
+ });
+
describe('OTPCodeControl', () => {
it('renders 6 "fake" input fields by default', async () => {
const { wrapper } = await createFixtures();