create-react-docs-ui 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/template/package.json +1 -1
- package/template/public/docs/en/docs/test/mdx-test.mdx +4 -18
- package/template/public/docs/zh-cn/docs/test/mdx-test.mdx +3 -1
- package/template/public/images/success.svg +1 -0
- package/template/src/components/Alert.tsx +121 -9
- package/template/src/components/BadgeList.tsx +72 -9
- package/template/src/components/Callout.tsx +49 -5
- package/template/src/components/Feature.tsx +2 -2
- package/template/src/components/MyTip.tsx +2 -2
- package/template/src/main.tsx +1 -1
- package/template/src/components/StepList.tsx +0 -62
package/package.json
CHANGED
package/template/package.json
CHANGED
|
@@ -50,6 +50,10 @@ The Alert component supports multiple types: info, success, warning, error
|
|
|
50
50
|
An error occurred, please check and try again.
|
|
51
51
|
</Alert>
|
|
52
52
|
|
|
53
|
+
<Alert type="success" title="Success" icon="/images/success.svg">
|
|
54
|
+
Congratulations! The operation has been completed successfully.
|
|
55
|
+
</Alert>
|
|
56
|
+
|
|
53
57
|
### Feature Component
|
|
54
58
|
|
|
55
59
|
The Feature component is used to display feature highlights:
|
|
@@ -86,24 +90,6 @@ The Callout component is used to emphasize important content:
|
|
|
86
90
|
This is a secondary style Callout used for supplementary information.
|
|
87
91
|
</Callout>
|
|
88
92
|
|
|
89
|
-
### StepList Component
|
|
90
|
-
|
|
91
|
-
The StepList component is used to display step processes:
|
|
92
|
-
|
|
93
|
-
<StepList>
|
|
94
|
-
<StepList.Step title="Install Dependencies">
|
|
95
|
-
Run the `npm install` command to install the required dependencies for the project.
|
|
96
|
-
</StepList.Step>
|
|
97
|
-
<StepList.Step title="Configure Environment">
|
|
98
|
-
Configure environment variables and development environment according to project requirements.
|
|
99
|
-
</StepList.Step>
|
|
100
|
-
<StepList.Step title="Start Project">
|
|
101
|
-
Run `npm run dev` to start the development server.
|
|
102
|
-
</StepList.Step>
|
|
103
|
-
<StepList.Step title="Start Development">
|
|
104
|
-
Start writing code to implement your functional requirements.
|
|
105
|
-
</StepList.Step>
|
|
106
|
-
</StepList>
|
|
107
93
|
|
|
108
94
|
### BadgeList Component
|
|
109
95
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d="M434.8 70.1c14.3 10.4 17.5 30.4 7.1 44.7l-256 352c-5.5 7.6-14 12.3-23.4 13.1s-18.5-2.7-25.1-9.3l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l101.5 101.5 234-321.7c10.4-14.3 30.4-17.5 44.7-7.1z"/></svg>
|
|
@@ -3,27 +3,139 @@ import * as React from 'react'
|
|
|
3
3
|
interface AlertProps {
|
|
4
4
|
type?: 'info' | 'success' | 'warning' | 'error'
|
|
5
5
|
title?: string
|
|
6
|
+
icon?: string | React.ReactNode
|
|
6
7
|
children: React.ReactNode
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
export function Alert({ type = 'info', title, children }: AlertProps) {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
export function Alert({ type = 'info', title, icon, children }: AlertProps) {
|
|
11
|
+
const [isDarkMode, setIsDarkMode] = React.useState(false)
|
|
12
|
+
|
|
13
|
+
React.useEffect(() => {
|
|
14
|
+
setIsDarkMode(document.documentElement.classList.contains('dark'))
|
|
15
|
+
const observer = new MutationObserver(() => {
|
|
16
|
+
setIsDarkMode(document.documentElement.classList.contains('dark'))
|
|
17
|
+
})
|
|
18
|
+
observer.observe(document.documentElement, {
|
|
19
|
+
attributes: true,
|
|
20
|
+
attributeFilter: ['class']
|
|
21
|
+
})
|
|
22
|
+
return () => observer.disconnect()
|
|
23
|
+
}, [])
|
|
24
|
+
|
|
25
|
+
const styles: Record<string, React.CSSProperties> = {
|
|
26
|
+
info: {
|
|
27
|
+
border: '1px solid #bfdbfe',
|
|
28
|
+
backgroundColor: '#eff6ff',
|
|
29
|
+
color: '#1e40af'
|
|
30
|
+
},
|
|
31
|
+
success: {
|
|
32
|
+
border: '1px solid #bbf7d0',
|
|
33
|
+
backgroundColor: '#f0fdf4',
|
|
34
|
+
color: '#166534'
|
|
35
|
+
},
|
|
36
|
+
warning: {
|
|
37
|
+
border: '1px solid #fef9c3',
|
|
38
|
+
backgroundColor: '#fefce8',
|
|
39
|
+
color: '#854d0e'
|
|
40
|
+
},
|
|
41
|
+
error: {
|
|
42
|
+
border: '1px solid #fecaca',
|
|
43
|
+
backgroundColor: '#fef2f2',
|
|
44
|
+
color: '#991b1b'
|
|
45
|
+
}
|
|
15
46
|
}
|
|
16
47
|
|
|
17
|
-
const
|
|
48
|
+
const darkStyles: Record<string, React.CSSProperties> = {
|
|
49
|
+
info: {
|
|
50
|
+
border: '1px solid rgba(30, 58, 138, 0.15)',
|
|
51
|
+
backgroundColor: 'rgba(30, 58, 138, 0.1)',
|
|
52
|
+
color: '#bfdbfe'
|
|
53
|
+
},
|
|
54
|
+
success: {
|
|
55
|
+
border: '1px solid rgba(22, 101, 52, 0.15)',
|
|
56
|
+
backgroundColor: 'rgba(22, 101, 52, 0.1)',
|
|
57
|
+
color: '#bbf7d0'
|
|
58
|
+
},
|
|
59
|
+
warning: {
|
|
60
|
+
border: '1px solid rgba(133, 77, 14, 0.15)',
|
|
61
|
+
backgroundColor: 'rgba(133, 77, 14, 0.1)',
|
|
62
|
+
color: '#fef9c3'
|
|
63
|
+
},
|
|
64
|
+
error: {
|
|
65
|
+
border: '1px solid rgba(153, 27, 27, 0.2)',
|
|
66
|
+
backgroundColor: 'rgba(153, 27, 27, 0.15)',
|
|
67
|
+
color: '#fecaca'
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const defaultIcons = {
|
|
18
72
|
info: 'ℹ️',
|
|
19
73
|
success: '✅',
|
|
20
74
|
warning: '⚠️',
|
|
21
75
|
error: '❌'
|
|
22
76
|
}
|
|
23
77
|
|
|
78
|
+
// 判断 icon 的类型并渲染
|
|
79
|
+
const renderIcon = () => {
|
|
80
|
+
if (icon === undefined) {
|
|
81
|
+
return defaultIcons[type]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (React.isValidElement(icon)) {
|
|
85
|
+
// 如果是 React 元素(如 SVG 组件)
|
|
86
|
+
const iconElement = icon as React.ReactElement<any>
|
|
87
|
+
return React.cloneElement(iconElement, {
|
|
88
|
+
style: {
|
|
89
|
+
display: 'inline-block',
|
|
90
|
+
verticalAlign: 'middle',
|
|
91
|
+
width: '1.25rem',
|
|
92
|
+
height: '1.25rem',
|
|
93
|
+
marginRight: '0.5rem',
|
|
94
|
+
...(iconElement.props?.style || {})
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (typeof icon === 'string' && icon.startsWith('/')) {
|
|
100
|
+
// 如果是路径字符串,渲染为图片
|
|
101
|
+
return (
|
|
102
|
+
<img
|
|
103
|
+
src={icon}
|
|
104
|
+
alt=""
|
|
105
|
+
style={{
|
|
106
|
+
display: 'inline-block',
|
|
107
|
+
verticalAlign: 'middle',
|
|
108
|
+
width: '1.25rem',
|
|
109
|
+
height: '1.25rem',
|
|
110
|
+
marginRight: '0.5rem'
|
|
111
|
+
}}
|
|
112
|
+
/>
|
|
113
|
+
)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 否则作为字符串渲染
|
|
117
|
+
return icon
|
|
118
|
+
}
|
|
119
|
+
|
|
24
120
|
return (
|
|
25
|
-
<div
|
|
26
|
-
|
|
121
|
+
<div style={{
|
|
122
|
+
margin: '1rem 0',
|
|
123
|
+
borderRadius: '0.5rem',
|
|
124
|
+
border: '1px solid',
|
|
125
|
+
padding: '1rem',
|
|
126
|
+
...(isDarkMode ? darkStyles[type] : styles[type])
|
|
127
|
+
}}>
|
|
128
|
+
{title && (
|
|
129
|
+
<div style={{
|
|
130
|
+
marginBottom: '0.5rem',
|
|
131
|
+
fontWeight: '600',
|
|
132
|
+
display: 'flex',
|
|
133
|
+
alignItems: 'center'
|
|
134
|
+
}}>
|
|
135
|
+
{renderIcon()}
|
|
136
|
+
<span>{title}</span>
|
|
137
|
+
</div>
|
|
138
|
+
)}
|
|
27
139
|
<div>{children}</div>
|
|
28
140
|
</div>
|
|
29
141
|
)
|
|
@@ -10,16 +10,74 @@ interface BadgeListProps {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
function Badge({ variant = 'default', children }: BadgeProps) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
const [isDarkMode, setIsDarkMode] = React.useState(false)
|
|
14
|
+
|
|
15
|
+
React.useEffect(() => {
|
|
16
|
+
setIsDarkMode(document.documentElement.classList.contains('dark'))
|
|
17
|
+
const observer = new MutationObserver(() => {
|
|
18
|
+
setIsDarkMode(document.documentElement.classList.contains('dark'))
|
|
19
|
+
})
|
|
20
|
+
observer.observe(document.documentElement, {
|
|
21
|
+
attributes: true,
|
|
22
|
+
attributeFilter: ['class']
|
|
23
|
+
})
|
|
24
|
+
return () => observer.disconnect()
|
|
25
|
+
}, [])
|
|
26
|
+
|
|
27
|
+
const styles: Record<string, React.CSSProperties> = {
|
|
28
|
+
default: {
|
|
29
|
+
backgroundColor: '#f3f4f6',
|
|
30
|
+
color: '#1f2937'
|
|
31
|
+
},
|
|
32
|
+
success: {
|
|
33
|
+
backgroundColor: '#dcfce7',
|
|
34
|
+
color: '#166534'
|
|
35
|
+
},
|
|
36
|
+
warning: {
|
|
37
|
+
backgroundColor: '#fef9c3',
|
|
38
|
+
color: '#854d0e'
|
|
39
|
+
},
|
|
40
|
+
error: {
|
|
41
|
+
backgroundColor: '#fee2e2',
|
|
42
|
+
color: '#991b1b'
|
|
43
|
+
},
|
|
44
|
+
info: {
|
|
45
|
+
backgroundColor: '#dbeafe',
|
|
46
|
+
color: '#1e40af'
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const darkStyles: Record<string, React.CSSProperties> = {
|
|
51
|
+
default: {
|
|
52
|
+
backgroundColor: 'rgba(55, 65, 81, 0.2)',
|
|
53
|
+
color: '#e5e7eb'
|
|
54
|
+
},
|
|
55
|
+
success: {
|
|
56
|
+
backgroundColor: 'rgba(22, 101, 52, 0.2)',
|
|
57
|
+
color: '#bbf7d0'
|
|
58
|
+
},
|
|
59
|
+
warning: {
|
|
60
|
+
backgroundColor: 'rgba(133, 77, 14, 0.2)',
|
|
61
|
+
color: '#fef9c3'
|
|
62
|
+
},
|
|
63
|
+
error: {
|
|
64
|
+
backgroundColor: 'rgba(153, 27, 27, 0.2)',
|
|
65
|
+
color: '#fecaca'
|
|
66
|
+
},
|
|
67
|
+
info: {
|
|
68
|
+
backgroundColor: 'rgba(30, 58, 138, 0.2)',
|
|
69
|
+
color: '#bfdbfe'
|
|
70
|
+
}
|
|
19
71
|
}
|
|
20
72
|
|
|
21
73
|
return (
|
|
22
|
-
<span
|
|
74
|
+
<span style={{
|
|
75
|
+
display: 'inline-block',
|
|
76
|
+
borderRadius: '9999px',
|
|
77
|
+
padding: '0.25rem 0.75rem',
|
|
78
|
+
fontSize: '0.875rem',
|
|
79
|
+
...(isDarkMode ? darkStyles[variant] : styles[variant])
|
|
80
|
+
}}>
|
|
23
81
|
{children}
|
|
24
82
|
</span>
|
|
25
83
|
)
|
|
@@ -27,8 +85,13 @@ function Badge({ variant = 'default', children }: BadgeProps) {
|
|
|
27
85
|
|
|
28
86
|
export function BadgeList({ children }: BadgeListProps) {
|
|
29
87
|
return (
|
|
30
|
-
<div
|
|
31
|
-
|
|
88
|
+
<div style={{
|
|
89
|
+
margin: '1rem 0',
|
|
90
|
+
display: 'flex',
|
|
91
|
+
flexWrap: 'wrap',
|
|
92
|
+
gap: '0.5rem'
|
|
93
|
+
}}>
|
|
94
|
+
{React.Children.map(children, child =>
|
|
32
95
|
React.isValidElement(child) ? child : null
|
|
33
96
|
)}
|
|
34
97
|
</div>
|
|
@@ -6,14 +6,58 @@ interface CalloutProps {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export function Callout({ variant = 'default', children }: CalloutProps) {
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const [isDarkMode, setIsDarkMode] = React.useState(false)
|
|
10
|
+
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
setIsDarkMode(document.documentElement.classList.contains('dark'))
|
|
13
|
+
const observer = new MutationObserver(() => {
|
|
14
|
+
setIsDarkMode(document.documentElement.classList.contains('dark'))
|
|
15
|
+
})
|
|
16
|
+
observer.observe(document.documentElement, {
|
|
17
|
+
attributes: true,
|
|
18
|
+
attributeFilter: ['class']
|
|
19
|
+
})
|
|
20
|
+
return () => observer.disconnect()
|
|
21
|
+
}, [])
|
|
22
|
+
|
|
23
|
+
const styles: Record<string, React.CSSProperties> = {
|
|
24
|
+
default: {
|
|
25
|
+
borderLeft: '4px solid #6b7280',
|
|
26
|
+
backgroundColor: '#f9fafb'
|
|
27
|
+
},
|
|
28
|
+
primary: {
|
|
29
|
+
borderLeft: '4px solid #3b82f6',
|
|
30
|
+
backgroundColor: '#eff6ff'
|
|
31
|
+
},
|
|
32
|
+
secondary: {
|
|
33
|
+
borderLeft: '4px solid #8b5cf6',
|
|
34
|
+
backgroundColor: '#faf5ff'
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const darkStyles: Record<string, React.CSSProperties> = {
|
|
39
|
+
default: {
|
|
40
|
+
borderLeft: '4px solid rgba(75, 85, 99, 0.2)',
|
|
41
|
+
backgroundColor: 'rgba(17, 24, 39, 0.2)'
|
|
42
|
+
},
|
|
43
|
+
primary: {
|
|
44
|
+
borderLeft: '4px solid rgba(30, 58, 138, 0.2)',
|
|
45
|
+
backgroundColor: 'rgba(30, 58, 138, 0.2)'
|
|
46
|
+
},
|
|
47
|
+
secondary: {
|
|
48
|
+
borderLeft: '4px solid rgba(88, 28, 135, 0.2)',
|
|
49
|
+
backgroundColor: 'rgba(88, 28, 135, 0.2)'
|
|
50
|
+
}
|
|
13
51
|
}
|
|
14
52
|
|
|
15
53
|
return (
|
|
16
|
-
<div
|
|
54
|
+
<div style={{
|
|
55
|
+
margin: '1rem 0',
|
|
56
|
+
borderTopRightRadius: '0.5rem',
|
|
57
|
+
borderBottomRightRadius: '0.5rem',
|
|
58
|
+
padding: '1rem',
|
|
59
|
+
...(isDarkMode ? darkStyles[variant] : styles[variant])
|
|
60
|
+
}}>
|
|
17
61
|
{children}
|
|
18
62
|
</div>
|
|
19
63
|
)
|
|
@@ -6,10 +6,10 @@ interface FeatureProps {
|
|
|
6
6
|
|
|
7
7
|
export function Feature({ icon = '🚀', title, description }: FeatureProps) {
|
|
8
8
|
return (
|
|
9
|
-
<div className="my-4 rounded-lg border border-gray-200 p-6 shadow-sm hover:shadow-md transition-shadow dark:border-gray-
|
|
9
|
+
<div className="my-4 rounded-lg border border-gray-200 p-6 shadow-sm hover:shadow-md transition-shadow dark:border-gray-600">
|
|
10
10
|
<div className="mb-3 text-4xl">{icon}</div>
|
|
11
11
|
<h3 className="mb-2 text-lg font-semibold">{title}</h3>
|
|
12
|
-
<p className="text-gray-600 dark:text-gray-
|
|
12
|
+
<p className="text-gray-600 dark:text-gray-400">{description}</p>
|
|
13
13
|
</div>
|
|
14
14
|
)
|
|
15
15
|
}
|
|
@@ -7,13 +7,13 @@ interface MyTipProps {
|
|
|
7
7
|
|
|
8
8
|
export function MyTip({ title, children }: MyTipProps) {
|
|
9
9
|
return (
|
|
10
|
-
<div className="my-4 rounded-lg border border-green-200 bg-green-50 p-4 dark:border-green-800 dark:bg-green-950">
|
|
10
|
+
<div className="my-4 rounded-lg border border-green-200 bg-green-50 p-4 dark:border-green-800/60 dark:bg-green-950/80">
|
|
11
11
|
{title && (
|
|
12
12
|
<div className="mb-2 font-semibold text-green-900 dark:text-green-100">
|
|
13
13
|
💡 {title}
|
|
14
14
|
</div>
|
|
15
15
|
)}
|
|
16
|
-
<div className="text-green-800 dark:text-green-
|
|
16
|
+
<div className="text-green-800 dark:text-green-300">{children}</div>
|
|
17
17
|
</div>
|
|
18
18
|
)
|
|
19
19
|
}
|
package/template/src/main.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import ReactDOM from "react-dom/client";
|
|
3
3
|
|
|
4
|
-
import "react-docs-ui/
|
|
4
|
+
import "react-docs-ui/style.css";
|
|
5
5
|
import { DocsApp } from "react-docs-ui";
|
|
6
6
|
// import "../../../react-docs-ui/dist/react-docs-ui.css";
|
|
7
7
|
// @ts-ignore using local built ES module for development
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
|
|
3
|
-
interface StepProps {
|
|
4
|
-
step: number
|
|
5
|
-
title: string
|
|
6
|
-
children: React.ReactNode
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
interface StepListProps {
|
|
10
|
-
children: React.ReactNode
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function Step({ step, title, 'data-title': dataTitle, children }: StepProps & { 'data-title'?: string }) {
|
|
14
|
-
// 优先使用 title,如果没有则使用 data-title
|
|
15
|
-
const displayTitle = title || dataTitle
|
|
16
|
-
|
|
17
|
-
return (
|
|
18
|
-
<div className="relative pb-8 last:pb-0">
|
|
19
|
-
<div className="absolute left-0 top-0 flex h-8 w-8 items-center justify-center rounded-full bg-blue-500 text-sm font-bold text-white">
|
|
20
|
-
{step}
|
|
21
|
-
</div>
|
|
22
|
-
<div className="ml-12">
|
|
23
|
-
<h4 className="mb-2 font-semibold">{displayTitle}</h4>
|
|
24
|
-
<div className="text-gray-600 dark:text-gray-300">{children}</div>
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function StepList({ children }: StepListProps) {
|
|
31
|
-
const steps = React.Children.toArray(children).filter(
|
|
32
|
-
(child): child is React.ReactElement<StepProps> => {
|
|
33
|
-
if (!React.isValidElement(child)) return false
|
|
34
|
-
|
|
35
|
-
const childProps = child.props as any
|
|
36
|
-
|
|
37
|
-
// 检查 props 中是否有 data-title 属性(通过我们的转换,title 变成了 data-title)
|
|
38
|
-
if (childProps && Object.prototype.hasOwnProperty.call(childProps, 'data-title')) return true
|
|
39
|
-
|
|
40
|
-
// 检查 props 中是否有 node.tagName === 'steplist-step'
|
|
41
|
-
if (childProps?.node?.tagName === 'steplist-step') return true
|
|
42
|
-
|
|
43
|
-
// 检查 props 中是否有 title 属性(直接使用的情况)
|
|
44
|
-
if (childProps && Object.prototype.hasOwnProperty.call(childProps, 'title')) return true
|
|
45
|
-
|
|
46
|
-
return false
|
|
47
|
-
}
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
return (
|
|
51
|
-
<div className="my-4 rounded-lg border border-gray-200 p-6 dark:border-gray-700">
|
|
52
|
-
{steps.map((step, index) =>
|
|
53
|
-
React.cloneElement(step, {
|
|
54
|
-
key: index,
|
|
55
|
-
step: index + 1
|
|
56
|
-
})
|
|
57
|
-
)}
|
|
58
|
-
</div>
|
|
59
|
-
)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
StepList.Step = Step
|