|
| 1 | +importReact,{FC,ReactNode,useState}from'react' |
| 2 | +import{Highlight,Language}from'prism-react-renderer' |
| 3 | + |
| 4 | +importCIconfrom'@coreui/icons-react' |
| 5 | +import{cibCodesandbox,cilCheckAlt,cilCopy}from'@coreui/icons' |
| 6 | +import{CNav,CNavLink,CTooltip,useClipboard}from'@coreui/react' |
| 7 | + |
| 8 | +import{openStackBlitzProject}from'../utils/stackblitz' |
| 9 | +import{openCodeSandboxProject}from'../utils/codesandbox' |
| 10 | + |
| 11 | +interfaceCodeSnippets{ |
| 12 | +js?:string |
| 13 | +ts?:string |
| 14 | +} |
| 15 | + |
| 16 | +interfaceExampleSnippetProps{ |
| 17 | +children:ReactNode |
| 18 | +className?:string |
| 19 | +code:string|CodeSnippets |
| 20 | +codeSandbox?:boolean |
| 21 | +componentName?:string |
| 22 | +stackBlitz?:boolean |
| 23 | +} |
| 24 | + |
| 25 | +constExampleSnippet:FC<ExampleSnippetProps>=({ |
| 26 | + children, |
| 27 | + className='', |
| 28 | + code, |
| 29 | + codeSandbox=true, |
| 30 | + componentName, |
| 31 | + stackBlitz=true, |
| 32 | +})=>{ |
| 33 | +const[language,setLanguage]=useState<'js'|'ts'>('js') |
| 34 | +const{ copy, isCopied}=useClipboard() |
| 35 | + |
| 36 | +// Type Guards to determine the shape of 'code' prop |
| 37 | +constisCodeString=typeofcode==='string' |
| 38 | +constcodeJS=isCodeString ?code :code.js||code.ts |
| 39 | +constcodeTS=isCodeString ?code :code.ts |
| 40 | +consthasJS=Boolean(codeJS) |
| 41 | +consthasTS=Boolean(codeTS) |
| 42 | + |
| 43 | +// Set initial language based on available code snippets |
| 44 | +React.useEffect(()=>{ |
| 45 | +if(!hasJS&&hasTS){ |
| 46 | +setLanguage('ts') |
| 47 | +}else{ |
| 48 | +setLanguage('js') |
| 49 | +} |
| 50 | +},[hasJS,hasTS]) |
| 51 | + |
| 52 | +consthandleCopy=()=>{ |
| 53 | +constcodeToCopy=language==='js' ?codeJS :codeTS |
| 54 | +if(codeToCopy){ |
| 55 | +copy(codeToCopy) |
| 56 | +} |
| 57 | +} |
| 58 | + |
| 59 | +constprismLanguage:Language=language==='js' ?'jsx' :'tsx' |
| 60 | + |
| 61 | +// Determine if both languages are available |
| 62 | +constshowJSTab=hasJS&&(isCodeString||code.js!==code.ts) |
| 63 | +constshowTSTab=hasTS |
| 64 | + |
| 65 | +return( |
| 66 | +<divclassName="docs-example-snippet"> |
| 67 | +{children&&<divclassName={`docs-example${className}`}>{children}</div>} |
| 68 | +<divclassName="highlight-toolbar border-top"> |
| 69 | +<CNavclassName="px-3"variant="underline-border"> |
| 70 | +{showJSTab&&( |
| 71 | +<CNavLinkas="button"active={language==='js'}onClick={()=>setLanguage('js')}> |
| 72 | + JavaScript |
| 73 | +</CNavLink> |
| 74 | +)} |
| 75 | +{showTSTab&&( |
| 76 | +<CNavLinkas="button"active={language==='ts'}onClick={()=>setLanguage('ts')}> |
| 77 | + TypeScript |
| 78 | +</CNavLink> |
| 79 | +)} |
| 80 | +<spanclassName="ms-auto"></span> |
| 81 | +{codeSandbox&&( |
| 82 | +<CTooltipcontent="Try it on CodeSandbox"> |
| 83 | +<button |
| 84 | +type="button" |
| 85 | +className="btn btn-transparent" |
| 86 | +aria-label="Try it on CodeSandbox" |
| 87 | +onClick={()=> |
| 88 | +openCodeSandboxProject({ |
| 89 | +name:React.isValidElement(children)&&(childrenasany).type?.name, |
| 90 | +language:language, |
| 91 | +code:language==='js' ?codeJS :codeTS||'', |
| 92 | + componentName, |
| 93 | +}) |
| 94 | +} |
| 95 | +disabled={language==='ts'&&!hasTS} |
| 96 | +> |
| 97 | +<CIconicon={cibCodesandbox}/> |
| 98 | +</button> |
| 99 | +</CTooltip> |
| 100 | +)} |
| 101 | +{stackBlitz&&( |
| 102 | +<CTooltipcontent="Try it on StackBlitz"> |
| 103 | +<button |
| 104 | +type="button" |
| 105 | +className="btn btn-transparent px-1" |
| 106 | +aria-label="Try it on StackBlitz" |
| 107 | +onClick={()=> |
| 108 | +openStackBlitzProject({ |
| 109 | +name:React.isValidElement(children)&&(childrenasany).type?.name, |
| 110 | +language:language, |
| 111 | +code:language==='js' ?codeJS :codeTS||'', |
| 112 | + componentName, |
| 113 | +}) |
| 114 | +} |
| 115 | +disabled={language==='ts'&&!hasTS} |
| 116 | +> |
| 117 | +<svg |
| 118 | +className="icon" |
| 119 | +width="56" |
| 120 | +height="78" |
| 121 | +viewBox="0 0 56 78" |
| 122 | +fill="none" |
| 123 | +xmlns="http://www.w3.org/2000/svg" |
| 124 | +> |
| 125 | +<path |
| 126 | +d="M23.4273 48.2853C23.7931 47.5845 23.0614 46.8837 22.3298 46.8837H1.11228C0.0148224 46.8837 -0.350997 45.8326 0.380642 45.1318L40.9866 0.282084C41.7182 -0.418693 43.1815 0.282084 42.8157 1.33325L32.9386 30.0651C32.5727 30.7659 32.9386 31.4666 33.6702 31.4666H54.8877C55.9852 31.4666 56.351 32.5178 55.6194 33.2186L15.0134 77.7179C14.2818 78.4187 12.8185 77.7179 13.1843 76.6667L23.4273 48.2853Z" |
| 127 | +fill="currentColor" |
| 128 | +/> |
| 129 | +</svg> |
| 130 | +</button> |
| 131 | +</CTooltip> |
| 132 | +)} |
| 133 | +<CTooltipcontent={isCopied ?'Copied' :'Copy to clipboard'}> |
| 134 | +<button |
| 135 | +type="button" |
| 136 | +className="btn btn-transparent px-1" |
| 137 | +aria-label="Copy to clipboard" |
| 138 | +onClick={handleCopy} |
| 139 | +disabled={(language==='js'&&!hasJS)||(language==='ts'&&!hasTS)} |
| 140 | +> |
| 141 | +<CIconicon={isCopied ?cilCheckAlt :cilCopy}/> |
| 142 | +</button> |
| 143 | +</CTooltip> |
| 144 | +</CNav> |
| 145 | +</div> |
| 146 | + |
| 147 | +<divclassName="highlight"> |
| 148 | +<Highlight |
| 149 | +code={language==='js' ?codeJS :codeTS||''} |
| 150 | +language={prismLanguage} |
| 151 | +theme={{plain:{},styles:[]}} |
| 152 | +> |
| 153 | +{({ className, style, tokens, getLineProps, getTokenProps})=>( |
| 154 | +<preclassName={className}style={style}> |
| 155 | +{tokens.map((line,i)=>( |
| 156 | +<div{...getLineProps({ line,key:i})}key={i}> |
| 157 | +{line.map((token,key)=>( |
| 158 | +<span{...getTokenProps({ token, key})}key={key}/> |
| 159 | +))} |
| 160 | +</div> |
| 161 | +))} |
| 162 | +</pre> |
| 163 | +)} |
| 164 | +</Highlight> |
| 165 | +</div> |
| 166 | +</div> |
| 167 | +) |
| 168 | +} |
| 169 | + |
| 170 | +ExampleSnippet.displayName='ExampleSnippet' |
| 171 | + |
| 172 | +exportdefaultExampleSnippet |