|
| 1 | +import { Slot } from '@radix-ui/react-slot'; |
| 2 | +import * as React from 'react'; |
| 3 | + |
| 4 | +import { CAPTCHA_ELEMENT_ID } from '~/internals/constants'; |
| 5 | +import { ClerkElementsRuntimeError } from '~/internals/errors'; |
| 6 | + |
| 7 | +import { SignUpStartCtx } from './start'; |
| 8 | + |
| 9 | +export type SignUpCaptchaElement = React.ElementRef<'div'>; |
| 10 | + |
| 11 | +type CaptchaElementProps = Omit< |
| 12 | + React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, |
| 13 | + 'id' | 'children' |
| 14 | +>; |
| 15 | + |
| 16 | +export type SignUpCaptchaProps = |
| 17 | + | ({ |
| 18 | + asChild: true; |
| 19 | + /* Must only be a self-closing element/component */ |
| 20 | + children: React.ReactElement; |
| 21 | + } & CaptchaElementProps) |
| 22 | + | ({ asChild?: false; children?: undefined } & CaptchaElementProps); |
| 23 | + |
| 24 | +/** |
| 25 | + * The `<SignUp.Captcha>` component is used to render the Cloudflare Turnstile widget. It must be used within the `<SignUp.Step name="start">` component. |
| 26 | + * |
| 27 | + * If utilizing the `asChild` prop, the component must be a self-closing element or component. Any children passed to the immediate child component of <SignUp.Captcha> will be ignored. |
| 28 | + * |
| 29 | + * @example |
| 30 | + * <SignUp.Root> |
| 31 | + * <SignUp.Step name="start"> |
| 32 | + * <SignUp.Captcha /> |
| 33 | + * <Clerk.Action submit>Sign Up</Clerk.Action> |
| 34 | + * </SignUp.Step> |
| 35 | + * </SignIn> |
| 36 | + * |
| 37 | + * @example |
| 38 | + * <SignUp.Root> |
| 39 | + * <SignUp.Step name="start"> |
| 40 | + * <SignUp.Captcha asChild> |
| 41 | + * <aside/> |
| 42 | + * </SignUp.Captcha> |
| 43 | + * <Clerk.Action submit>Sign Up</Clerk.Action> |
| 44 | + * </SignUp.Step> |
| 45 | + * </SignIn> |
| 46 | + */ |
| 47 | + |
| 48 | +export const SignUpCaptcha = React.forwardRef<SignUpCaptchaElement, SignUpCaptchaProps>( |
| 49 | + ({ asChild, children, ...rest }, forwardedRef) => { |
| 50 | + const ref = SignUpStartCtx.useActorRef(true); |
| 51 | + |
| 52 | + if (!ref) { |
| 53 | + throw new ClerkElementsRuntimeError( |
| 54 | + '<SignUp.Captcha> must be used within the <SignUp.Step name="start"> component.', |
| 55 | + ); |
| 56 | + } |
| 57 | + |
| 58 | + const Comp = asChild ? Slot : 'div'; |
| 59 | + |
| 60 | + return ( |
| 61 | + <Comp |
| 62 | + id={CAPTCHA_ELEMENT_ID} |
| 63 | + {...rest} |
| 64 | + ref={forwardedRef} |
| 65 | + /> |
| 66 | + ); |
| 67 | + }, |
| 68 | +); |
0 commit comments