Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit29e5aff

Browse files
committed
docs: add ExampleSnippet component
1 parent9680566 commit29e5aff

File tree

13 files changed

+536
-31
lines changed

13 files changed

+536
-31
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import{useClipboard}from'./useClipboard'
12
import{useColorModes}from'./useColorModes'
23
import{useForkedRef}from'./useForkedRef'
34
import{usePopper}from'./usePopper'
45

5-
export{useColorModes,useForkedRef,usePopper}
6+
export{useClipboard,useColorModes,useForkedRef,usePopper}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import{useState,useCallback}from'react'
2+
3+
/**
4+
* useClipboard Hook
5+
*
6+
* Provides functionality to copy text to the clipboard and track the copy status.
7+
*
8+
*@returns An object containing the copy function, copy status, and any error encountered.
9+
*/
10+
exportconstuseClipboard=()=>{
11+
const[isCopied,setIsCopied]=useState<boolean>(false)
12+
const[error,setError]=useState<Error|null>(null)
13+
14+
/**
15+
* Copies the provided text to the clipboard.
16+
*
17+
*@param text - The text to be copied to the clipboard.
18+
*/
19+
constcopy=useCallback(async(text:string)=>{
20+
if(!navigator?.clipboard){
21+
setError(newError('Clipboard API is not available'))
22+
return
23+
}
24+
25+
try{
26+
awaitnavigator.clipboard.writeText(text)
27+
setIsCopied(true)
28+
setError(null)
29+
// Reset the isCopied state after 2 seconds
30+
setTimeout(()=>setIsCopied(false),2000)
31+
}catch(_error){
32+
setError(_errorasError)
33+
setIsCopied(false)
34+
}
35+
},[])
36+
37+
return{ copy, isCopied, error}
38+
}

‎packages/docs/gatsby-node.mjs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export const createPages = async ({
6868
context:{
6969
id:node.id,
7070
route:node.frontmatter.route,
71+
regex:`/^${node.frontmatter.route}/`,
7172
},
7273
})
7374
})

‎packages/docs/package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"author":"The CoreUI Team (https://github.com/orgs/coreui/people)",
1616
"scripts": {
1717
"api":"rimraf\"content/api/*\" & node build/api.mjs",
18-
"build":"gatsby build",
18+
"build":"gatsby build --prefix-paths",
1919
"develop":"gatsby develop",
2020
"dist":"run-s api build",
2121
"format":"prettier --write\"**/*.{js,jsx,ts,tsx,json,md}\"",
@@ -33,6 +33,7 @@
3333
"@docsearch/css":"^3.6.2",
3434
"@mdx-js/mdx":"^3.1.0",
3535
"@mdx-js/react":"^3.1.0",
36+
"@stackblitz/sdk":"^1.11.0",
3637
"@types/react-helmet":"^6.1.11",
3738
"gatsby":"^5.13.7",
3839
"gatsby-plugin-google-tagmanager":"^5.13.1",
@@ -58,7 +59,6 @@
5859
"react-helmet":"^6.1.0",
5960
"react-imask":"^7.6.1",
6061
"react-markdown":"^9.0.1",
61-
"remark-mdx":"^1.6.22",
6262
"rimraf":"^6.0.1",
6363
"sass":"^1.80.4"
6464
},
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
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

‎packages/docs/src/components/index.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Callout from './Callout'
44
importCodeBlockfrom'./CodeBlock'
55
importClassNamesDocsfrom'./ClassNamesDocs'
66
importExamplefrom'./Example'
7+
importExampleSnippetfrom'./ExampleSnippet'
78
importFooterfrom'./Footer'
89
importHeaderfrom'./Header'
910
importJSXDocsfrom'./JSXDocs'
@@ -20,6 +21,7 @@ export {
2021
CodeBlock,
2122
ClassNamesDocs,
2223
Example,
24+
ExampleSnippet,
2325
Footer,
2426
Header,
2527
JSXDocs,

‎packages/docs/src/pages/404.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react'
22
import{graphql,useStaticQuery}from'gatsby'
33
import{CButton}from'@coreui/react/src/index'
44

5-
importSeofrom'./../components/Seo'
5+
importSeofrom'../components/Seo'
66

77
constNotFoundPage=()=>{
88
const{ site}=useStaticQuery(query)

‎packages/docs/src/styles/_component-examples.scss‎

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,39 @@
2727
.docs-example-snippet {
2828
border:solidvar(--cui-border-color);
2929
border-width:1px0;
30+
margin:0 ($cd-gutter-x *-.5)1rem ($cd-gutter-x *-.5);
31+
padding:0;
32+
@includeborder-radius(0);
3033

31-
@includemedia-breakpoint-up(md) {
34+
.docs-example {
35+
margin:0;
36+
padding:1rem;
37+
border-width:01px00;
38+
}
39+
40+
.highlight-toolbar {
41+
border-top:1pxsolidvar(--cui-border-color);
42+
}
43+
44+
.highlight {
45+
margin:0;
46+
padding:1rem;
47+
}
48+
49+
.docs-example,
50+
.highlight {
51+
border:0
52+
}
53+
54+
.highlight {
55+
margin-bottom:0;
56+
@includeborder-top-radius(0);
57+
}
58+
59+
@includemedia-breakpoint-up(sm) {
60+
margin:001rem0;
3261
border-width:1px;
62+
@includeborder-radius(var(--cui-border-radius));
3363
}
3464
}
3565

‎packages/docs/src/templates/DocsLayout.tsx‎

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,13 @@ const DocsLayout: FC<DocsLayoutProps> = ({ children, data, location, pageContext
3232
constframeworks=other_frameworks ?other_frameworks.split(', ') :false
3333
constotherFrameworks=JSON.parse(JSON.stringify(jsonData))
3434

35-
consthasNav=data.allMdx.edges.length>1
36-
consthasNavAccesibility=data.allMdx.edges.filter((edge:any)=>
37-
edge.node.frontmatter.title.includes('Accesibility'),
38-
).length
39-
consthasNavAPI=data.allMdx.edges.filter((edge:any)=>
40-
edge.node.frontmatter.title.includes('API'),
41-
).length
42-
consthasNavCustomizing=data.allMdx.edges.filter((edge:any)=>
43-
edge.node.frontmatter.title.includes('Customizing'),
44-
).length
35+
consthasNav=data?.allMdx?.edges.length>1
36+
consthasNavAccesibility=
37+
hasNav&&data.allMdx.edges.some((edge:any)=>edge.node.fields.slug.includes('accesibility'))
38+
consthasNavAPI=
39+
hasNav&&data.allMdx.edges.some((edge:any)=>edge.node.fields.slug.includes('api'))
40+
consthasNavCustomizing=
41+
hasNav&&data.allMdx.edges.some((edge:any)=>edge.node.fields.slug.includes('customizing'))
4542

4643
return(
4744
<>
@@ -52,7 +49,7 @@ const DocsLayout: FC<DocsLayoutProps> = ({ children, data, location, pageContext
5249
<CNavclassName="ms-lg-4 docs-nav bg-body"variant="underline-border">
5350
<CNavItem>
5451
<CNavLinkhref={`${route}`}active={route===location.pathname}>
55-
Overview
52+
Features
5653
</CNavLink>
5754
</CNavItem>
5855
{hasNavAPI&&(

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp