UNPKG

@marsidev/react-turnstile

Version:

Cloudflare Turnstile integration for React.

3 lines (2 loc) 6.19 kB
'use client'; import{forwardRef as pe,useCallback as Q,useEffect as h,useImperativeHandle as fe,useMemo as me,useRef as D,useState as Z}from"react";import{forwardRef as ce}from"react";import{jsx as ue}from"react/jsx-runtime";var ae=({as:n="div",...a},s)=>ue(n,{...a,ref:s}),J=ce(ae);import{useEffect as le,useState as de}from"react";var K="https://challenges.cloudflare.com/turnstile/v0/api.js",b="cf-turnstile-script",U="cf-turnstile",P="onloadTurnstileCallback",M=n=>!!document.getElementById(n),X=({render:n="explicit",onLoadCallbackName:a=P,scriptOptions:{nonce:s="",defer:e=!0,async:m=!0,id:v="",appendTo:g,onError:T,crossOrigin:w=""}={}})=>{let E=v||b;if(M(E))return;let i=document.createElement("script");if(i.id=E,i.src=`${K}?onload=${a}&render=${n}`,document.querySelector(`script[src="${i.src}"]`))return;i.defer=!!e,i.async=!!m,s&&(i.nonce=s),w&&(i.crossOrigin=w),T&&(i.onerror=T,delete window[a]),(g==="body"?document.body:document.getElementsByTagName("head")[0]).appendChild(i)},f={normal:{width:300,height:65},compact:{width:150,height:140},invisible:{width:0,height:0,overflow:"hidden"},flexible:{minWidth:300,width:"100%",height:65},interactionOnly:{width:"fit-content",height:"auto",display:"flex"}};function G(n){if(n!=="invisible"&&n!=="interactionOnly")return n}function z(n=b){let[a,s]=de(!1);return le(()=>{let e=()=>{M(n)&&s(!0)},m=new MutationObserver(e);return m.observe(document,{childList:!0,subtree:!0}),e(),()=>{m.disconnect()}},[n]),a}import{jsx as xe}from"react/jsx-runtime";var _="unloaded",ee,Te=new Promise((n,a)=>{ee={resolve:n,reject:a},_==="ready"&&n(void 0)}),we=(n=P)=>(_==="unloaded"&&(_="loading",window[n]=()=>{ee.resolve(),_="ready",delete window[n]}),Te),Ee=pe((n,a)=>{let{scriptOptions:s,options:e={},siteKey:m,onWidgetLoad:v,onSuccess:g,onExpire:T,onError:w,onBeforeInteractive:E,onAfterInteractive:i,onUnsupported:I,onTimeout:k,onLoadScript:W,id:te,style:re,as:ne="div",injectScript:$=!0,rerenderOnCallbackChange:o=!1,...oe}=n,c=e.size,j=Q(()=>typeof c>"u"?{}:e.execution==="execute"?f.invisible:e.appearance==="interaction-only"?f.interactionOnly:f[c],[e.execution,c,e.appearance]),[ie,R]=Z(j()),u=D(null),[x,B]=Z(!1),r=D(void 0),L=D(!1),H=te||U,d=D({onSuccess:g,onError:w,onExpire:T,onBeforeInteractive:E,onAfterInteractive:i,onUnsupported:I,onTimeout:k});h(()=>{o||(d.current={onSuccess:g,onError:w,onExpire:T,onBeforeInteractive:E,onAfterInteractive:i,onUnsupported:I,onTimeout:k})});let O=s?.id||b,A=z(O),V=s?.onLoadCallbackName||P,se=e.appearance||"always",C=me(()=>({sitekey:m,action:e.action,cData:e.cData,theme:e.theme||"auto",language:e.language||"auto",tabindex:e.tabIndex,"response-field":e.responseField,"response-field-name":e.responseFieldName,size:G(c),retry:e.retry||"auto","retry-interval":e.retryInterval||8e3,"refresh-expired":e.refreshExpired||"auto","refresh-timeout":e.refreshTimeout||"auto",execution:e.execution||"render",appearance:e.appearance||"always","feedback-enabled":e.feedbackEnabled||!0,callback:t=>{L.current=!0,o?g?.(t):d.current.onSuccess?.(t)},"error-callback":o?w:(...t)=>d.current.onError?.(...t),"expired-callback":o?T:(...t)=>d.current.onExpire?.(...t),"before-interactive-callback":o?E:(...t)=>d.current.onBeforeInteractive?.(...t),"after-interactive-callback":o?i:(...t)=>d.current.onAfterInteractive?.(...t),"unsupported-callback":o?I:(...t)=>d.current.onUnsupported?.(...t),"timeout-callback":o?k:(...t)=>d.current.onTimeout?.(...t)}),[e.action,e.appearance,e.cData,e.execution,e.language,e.refreshExpired,e.responseField,e.responseFieldName,e.retry,e.retryInterval,e.tabIndex,e.theme,e.feedbackEnabled,e.refreshTimeout,m,c,o,o?g:null,o?w:null,o?T:null,o?E:null,o?i:null,o?I:null,o?k:null]),y=Q(()=>typeof window<"u"&&!!window.turnstile,[]);return h(function(){$&&!x&&X({onLoadCallbackName:V,scriptOptions:{...s,id:O}})},[$,x,s,O]),h(function(){_!=="ready"&&we(V).then(()=>B(!0)).catch(console.error)},[]),h(function(){if(!u.current||!x)return;let l=!1;return(async()=>{if(l||!u.current)return;let F=window.turnstile.render(u.current,C);r.current=F,r.current&&v?.(r.current)})(),()=>{l=!0,r.current&&(window.turnstile.remove(r.current),L.current=!1)}},[H,x,C]),fe(a,()=>{let{turnstile:t}=window;return{getResponse(){if(!t?.getResponse||!r.current||!y()){console.warn("Turnstile has not been loaded");return}return t.getResponse(r.current)},async getResponsePromise(l=3e4,Y=100){return new Promise((F,N)=>{let p,q=async()=>{if(L.current&&window.turnstile&&r.current)try{let S=window.turnstile.getResponse(r.current);return p&&clearTimeout(p),S?F(S):N(new Error("No response received"))}catch(S){return p&&clearTimeout(p),console.warn("Failed to get response",S),N(new Error("Failed to get response"))}p||(p=setTimeout(()=>{p&&clearTimeout(p),N(new Error("Timeout"))},l)),await new Promise(S=>setTimeout(S,Y)),await q()};q()})},reset(){if(!t?.reset||!r.current||!y()){console.warn("Turnstile has not been loaded");return}e.execution==="execute"&&R(f.invisible);try{L.current=!1,t.reset(r.current)}catch(l){console.warn(`Failed to reset Turnstile widget ${r}`,l)}},remove(){if(!t?.remove||!r.current||!y()){console.warn("Turnstile has not been loaded");return}R(f.invisible),L.current=!1,t.remove(r.current),r.current=null},render(){if(!t?.render||!u.current||!y()||r.current){console.warn("Turnstile has not been loaded or container not found");return}let l=t.render(u.current,C);return r.current=l,r.current&&v?.(r.current),e.execution!=="execute"&&R(c?f[c]:{}),l},execute(){if(e.execution!=="execute"){console.warn('Execution mode is not set to "execute"');return}if(!t?.execute||!u.current||!r.current||!y()){console.warn("Turnstile has not been loaded or container not found");return}t.execute(u.current,C),R(c?f[c]:{})},isExpired(){return!t?.isExpired||!r.current||!y()?(console.warn("Turnstile has not been loaded"),!1):t.isExpired(r.current)}}},[r,e.execution,c,C,u,y,x,v]),h(()=>{A&&!x&&window.turnstile&&B(!0)},[x,A]),h(()=>{R(j())},[e.execution,c,se]),h(()=>{!A||typeof W!="function"||W()},[A]),xe(J,{ref:u,as:ne,id:H,style:{...ie,...re},...oe})});Ee.displayName="Turnstile";export{U as DEFAULT_CONTAINER_ID,P as DEFAULT_ONLOAD_NAME,b as DEFAULT_SCRIPT_ID,K as SCRIPT_URL,Ee as Turnstile};