@zat-design/sisyphus-react 3.1.4 → 3.1.5-beta.10
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/.dumi/theme/builtins/Alert.tsx +19 -0
- package/.dumi/theme/builtins/Previewer.tsx +232 -0
- package/.dumi/theme/builtins/SourceCode.tsx +64 -0
- package/.dumi/theme/hooks/useCodeSandbox.tsx +197 -0
- package/.dumi/theme/hooks/useTheme.tsx +707 -0
- package/.dumi/theme/layouts/BasicLayout.tsx +88 -0
- package/.dumi/theme/layouts/components/Dark.less +157 -0
- package/.dumi/theme/layouts/components/Dark.tsx +78 -0
- package/.dumi/theme/layouts/components/Navbar.tsx +83 -0
- package/.dumi/theme/layouts/components/SideMenu.tsx +61 -0
- package/.dumi/theme/layouts/index.tsx +26 -0
- package/.dumi/theme/layouts/layout.less +87 -0
- package/.dumi/theme/typings.d.ts +7 -0
- package/dist/index.esm.css +122 -249
- package/es/ProAction/index.less +3 -2
- package/es/ProConfigProvider/index.d.ts +2 -0
- package/es/ProConfigProvider/index.js +18 -2
- package/es/ProDrawerForm/index.js +5 -3
- package/es/ProDrawerForm/style/index.less +15 -11
- package/es/ProEditLabel/style/index.less +2 -2
- package/es/ProEditTable/style/index.less +15 -8
- package/es/ProEditTable/utils/config.js +11 -4
- package/es/ProEnum/style/index.less +1 -1
- package/es/ProForm/components/base/RangePicker/index.js +0 -3
- package/es/ProForm/components/base/TextArea/index.less +1 -1
- package/es/ProForm/components/combination/Container/style/index.less +0 -1
- package/es/ProForm/components/combination/FormList/style/index.less +20 -19
- package/es/ProForm/components/combination/Group/index.js +2 -2
- package/es/ProForm/components/combination/ProAddressBar/index.js +81 -61
- package/es/ProForm/components/combination/ProAddressBar/propsType.d.ts +3 -2
- package/es/ProForm/components/combination/ProModalSelect/index.js +75 -13
- package/es/ProForm/components/combination/ProModalSelect/propsType.d.ts +1 -0
- package/es/ProForm/components/combination/ProModalSelect/style/index.less +3 -3
- package/es/ProForm/components/combination/ProNumberRange/style/index.less +1 -1
- package/es/ProForm/components/combination/ProRangeLimit/index.d.ts +1 -1
- package/es/ProForm/components/combination/ProTimeLimit/index.d.ts +10 -5
- package/es/ProForm/components/combination/ProTimeLimit/style/index.less +1 -1
- package/es/ProForm/components/old/EnumSelect/style/index.less +7 -8
- package/es/ProForm/components/render/RenderFields.js +10 -5
- package/es/ProForm/components/render/propsType.d.ts +5 -4
- package/es/ProForm/index.js +5 -0
- package/es/ProForm/style/index.less +55 -169
- package/es/ProForm/utils/useShouldUpdate.js +16 -16
- package/es/ProLayout/components/Layout/Menu/OpenMenu/style/index.less +2 -2
- package/es/ProLayout/components/ProCollapse/style/index.less +4 -4
- package/es/ProLayout/components/ProHeader/components/ProBackBtn/style/index.less +21 -0
- package/es/ProLayout/components/ProHeader/components/index.d.ts +1 -0
- package/es/ProLayout/components/ProHeader/components/index.js +2 -1
- package/es/ProLayout/components/ProHeader/index.js +4 -2
- package/es/ProLayout/components/ProHeader/style/index.less +16 -7
- package/es/ProStep/style/index.less +0 -1
- package/es/ProTable/components/RenderColumn/index.d.ts +5 -5
- package/es/ProTable/components/RenderColumn/index.js +41 -25
- package/es/ProTable/index.js +3 -2
- package/es/ProTable/propsType.d.ts +2 -0
- package/es/ProTable/style/index.less +14 -1
- package/es/ProTable/utils.d.ts +1 -1
- package/es/ProTable/utils.js +258 -201
- package/es/ProTabs/style/index.less +1 -1
- package/es/ProThemeTools/component/PrdTools/index.js +1 -1
- package/es/ProThemeTools/component/PrdTools/style/index.less +3 -3
- package/es/ProThemeTools/index.d.ts +2 -2
- package/es/ProThemeTools/index.js +24 -17
- package/es/ProThemeTools/propsType.d.ts +8 -6
- package/es/ProThemeTools/style/index.less +2 -2
- package/es/ProThemeTools/utils/index.d.ts +7 -0
- package/es/ProThemeTools/utils/index.js +19 -1
- package/es/ProTree/components/ProTree.js +1 -1
- package/es/ProTree/components/SearchTitle.d.ts +2 -2
- package/es/ProTree/components/SearchTitle.js +11 -1
- package/es/ProTree/components/Tree.js +6 -1
- package/es/ProTree/style/index.less +193 -141
- package/es/ProTreeModal/style/index.less +2 -6
- package/es/ProUpload/style/index.less +41 -39
- package/es/index.d.ts +2 -1
- package/es/index.js +2 -1
- package/es/locale/en_US.d.ts +69 -0
- package/es/locale/en_US.js +68 -0
- package/es/locale/index.d.ts +7 -0
- package/es/locale/index.js +21 -0
- package/es/locale/zh_CN.d.ts +69 -0
- package/es/locale/zh_CN.js +68 -0
- package/es/old/ProEditableTable/style/index.less +1 -2
- package/es/style/components.less +0 -1
- package/es/style/core/normalize.less +1 -1
- package/es/style/theme/antd.less +3 -4
- package/es/style/theme/index.less +80 -79
- package/es/style/theme/tokens.less +1 -0
- package/lib/ProAction/index.less +3 -2
- package/lib/ProConfigProvider/index.d.ts +2 -0
- package/lib/ProConfigProvider/index.js +17 -2
- package/lib/ProDrawerForm/index.js +5 -3
- package/lib/ProDrawerForm/style/index.less +15 -11
- package/lib/ProEditLabel/style/index.less +2 -2
- package/lib/ProEditTable/style/index.less +15 -8
- package/lib/ProEditTable/utils/config.js +11 -4
- package/lib/ProEnum/style/index.less +1 -1
- package/lib/ProForm/components/base/RangePicker/index.js +0 -3
- package/lib/ProForm/components/base/TextArea/index.less +1 -1
- package/lib/ProForm/components/combination/Container/style/index.less +0 -1
- package/lib/ProForm/components/combination/FormList/style/index.less +20 -19
- package/lib/ProForm/components/combination/Group/index.js +2 -2
- package/lib/ProForm/components/combination/ProAddressBar/index.js +76 -58
- package/lib/ProForm/components/combination/ProAddressBar/propsType.d.ts +3 -2
- package/lib/ProForm/components/combination/ProModalSelect/index.js +75 -13
- package/lib/ProForm/components/combination/ProModalSelect/propsType.d.ts +1 -0
- package/lib/ProForm/components/combination/ProModalSelect/style/index.less +3 -3
- package/lib/ProForm/components/combination/ProNumberRange/style/index.less +1 -1
- package/lib/ProForm/components/combination/ProRangeLimit/index.d.ts +1 -1
- package/lib/ProForm/components/combination/ProTimeLimit/index.d.ts +10 -5
- package/lib/ProForm/components/combination/ProTimeLimit/style/index.less +1 -1
- package/lib/ProForm/components/old/EnumSelect/style/index.less +7 -8
- package/lib/ProForm/components/render/RenderFields.js +9 -4
- package/lib/ProForm/components/render/propsType.d.ts +5 -4
- package/lib/ProForm/index.js +5 -0
- package/lib/ProForm/style/index.less +55 -169
- package/lib/ProForm/utils/useShouldUpdate.js +16 -16
- package/lib/ProLayout/components/Layout/Menu/OpenMenu/style/index.less +2 -2
- package/lib/ProLayout/components/ProCollapse/style/index.less +4 -4
- package/lib/ProLayout/components/ProHeader/components/ProBackBtn/style/index.less +21 -0
- package/lib/ProLayout/components/ProHeader/components/index.d.ts +1 -0
- package/lib/ProLayout/components/ProHeader/components/index.js +8 -1
- package/lib/ProLayout/components/ProHeader/index.js +4 -2
- package/lib/ProLayout/components/ProHeader/style/index.less +16 -7
- package/lib/ProStep/style/index.less +0 -1
- package/lib/ProTable/components/RenderColumn/index.d.ts +5 -5
- package/lib/ProTable/components/RenderColumn/index.js +38 -24
- package/lib/ProTable/index.js +3 -2
- package/lib/ProTable/propsType.d.ts +2 -0
- package/lib/ProTable/style/index.less +14 -1
- package/lib/ProTable/utils.d.ts +1 -1
- package/lib/ProTable/utils.js +258 -201
- package/lib/ProTabs/style/index.less +1 -1
- package/lib/ProThemeTools/component/PrdTools/index.js +1 -1
- package/lib/ProThemeTools/component/PrdTools/style/index.less +3 -3
- package/lib/ProThemeTools/index.d.ts +2 -2
- package/lib/ProThemeTools/index.js +23 -16
- package/lib/ProThemeTools/propsType.d.ts +8 -6
- package/lib/ProThemeTools/style/index.less +2 -2
- package/lib/ProThemeTools/utils/index.d.ts +7 -0
- package/lib/ProThemeTools/utils/index.js +20 -2
- package/lib/ProTree/components/ProTree.js +1 -1
- package/lib/ProTree/components/SearchTitle.d.ts +2 -2
- package/lib/ProTree/components/SearchTitle.js +11 -1
- package/lib/ProTree/components/Tree.js +6 -1
- package/lib/ProTree/style/index.less +193 -141
- package/lib/ProTreeModal/style/index.less +2 -6
- package/lib/ProUpload/style/index.less +41 -39
- package/lib/index.d.ts +2 -1
- package/lib/index.js +13 -1
- package/lib/locale/en_US.d.ts +69 -0
- package/lib/locale/en_US.js +74 -0
- package/lib/locale/index.d.ts +7 -0
- package/lib/locale/index.js +28 -0
- package/lib/locale/zh_CN.d.ts +69 -0
- package/lib/locale/zh_CN.js +74 -0
- package/lib/old/ProEditableTable/style/index.less +1 -2
- package/lib/style/components.less +0 -1
- package/lib/style/core/normalize.less +1 -1
- package/lib/style/theme/antd.less +3 -4
- package/lib/style/theme/index.less +80 -79
- package/lib/style/theme/tokens.less +1 -0
- package/package.json +2 -2
- package/typings.d.ts +2 -0
- package/es/old/ProBackBtn/style/index.less +0 -19
- package/lib/old/ProBackBtn/style/index.less +0 -19
- /package/es/{old → ProLayout/components/ProHeader/components}/ProBackBtn/index.d.ts +0 -0
- /package/es/{old → ProLayout/components/ProHeader/components}/ProBackBtn/index.js +0 -0
- /package/es/{old → ProLayout/components/ProHeader/components}/ProBackBtn/propsType.d.ts +0 -0
- /package/es/{old → ProLayout/components/ProHeader/components}/ProBackBtn/propsType.js +0 -0
- /package/lib/{old → ProLayout/components/ProHeader/components}/ProBackBtn/index.d.ts +0 -0
- /package/lib/{old → ProLayout/components/ProHeader/components}/ProBackBtn/index.js +0 -0
- /package/lib/{old → ProLayout/components/ProHeader/components}/ProBackBtn/propsType.d.ts +0 -0
- /package/lib/{old → ProLayout/components/ProHeader/components}/ProBackBtn/propsType.js +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { InfoCircleFilled } from '@ant-design/icons'
|
|
3
|
+
|
|
4
|
+
export default function MyAlert(props: any) {
|
|
5
|
+
return (
|
|
6
|
+
<span
|
|
7
|
+
style={{
|
|
8
|
+
display: 'block',
|
|
9
|
+
backgroundColor: '#e6f7ff',
|
|
10
|
+
border: '1px solid #91d5ff',
|
|
11
|
+
borderRadius: 2,
|
|
12
|
+
padding: '8px 15px'
|
|
13
|
+
}}
|
|
14
|
+
>
|
|
15
|
+
<InfoCircleFilled style={{ color: '#1890ff', marginRight: 8 }} />
|
|
16
|
+
{props.children}
|
|
17
|
+
</span>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import React, { useState, useContext, useRef, useEffect } from 'react'
|
|
2
|
+
import Tabs, { TabPane } from 'rc-tabs'
|
|
3
|
+
// @ts-ignore
|
|
4
|
+
import { history } from 'dumi'
|
|
5
|
+
import { IPreviewerComponentProps } from 'dumi/theme'
|
|
6
|
+
import {
|
|
7
|
+
context,
|
|
8
|
+
useRiddle,
|
|
9
|
+
useMotions,
|
|
10
|
+
useCopy,
|
|
11
|
+
useLocaleProps,
|
|
12
|
+
useDemoUrl,
|
|
13
|
+
useTSPlaygroundUrl,
|
|
14
|
+
Link,
|
|
15
|
+
AnchorLink,
|
|
16
|
+
usePrefersColor
|
|
17
|
+
} from 'dumi/theme'
|
|
18
|
+
import { ICodeBlockProps } from './SourceCode'
|
|
19
|
+
import SourceCode from './SourceCode'
|
|
20
|
+
import 'dumi-theme-default/src/builtins/Previewer.less'
|
|
21
|
+
import useCodeSandbox from '../hooks/useCodeSandbox'
|
|
22
|
+
|
|
23
|
+
export interface IPreviewerProps extends IPreviewerComponentProps {
|
|
24
|
+
/**
|
|
25
|
+
* enable transform to change CSS containing block for demo
|
|
26
|
+
*/
|
|
27
|
+
transform?: boolean
|
|
28
|
+
/**
|
|
29
|
+
* modify background for demo area
|
|
30
|
+
*/
|
|
31
|
+
background?: string
|
|
32
|
+
/**
|
|
33
|
+
* collapse padding of demo area
|
|
34
|
+
*/
|
|
35
|
+
compact?: boolean
|
|
36
|
+
/**
|
|
37
|
+
* configurations for action button
|
|
38
|
+
*/
|
|
39
|
+
hideActions?: ('CSB' | 'EXTERNAL' | 'RIDDLE')[]
|
|
40
|
+
/**
|
|
41
|
+
* show source code by default
|
|
42
|
+
*/
|
|
43
|
+
defaultShowCode?: boolean
|
|
44
|
+
/**
|
|
45
|
+
* use iframe mode for this demo
|
|
46
|
+
*/
|
|
47
|
+
iframe?: true | number
|
|
48
|
+
/**
|
|
49
|
+
* replace builtin demo url
|
|
50
|
+
*/
|
|
51
|
+
demoUrl?: string
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* get source code type for file
|
|
56
|
+
* @param file file path
|
|
57
|
+
* @param source file source object
|
|
58
|
+
*/
|
|
59
|
+
function getSourceType(file: string, source: IPreviewerComponentProps['sources']['_']) {
|
|
60
|
+
// use file extension as source type first
|
|
61
|
+
let type = file.match(/\.(\w+)$/)?.[1]
|
|
62
|
+
|
|
63
|
+
if (!type) {
|
|
64
|
+
type = source.tsx ? 'tsx' : 'jsx'
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return type as ICodeBlockProps['lang']
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const Previewer: React.FC<IPreviewerProps> = oProps => {
|
|
71
|
+
const demoRef = useRef()
|
|
72
|
+
const { locale } = useContext(context)
|
|
73
|
+
const props = useLocaleProps<IPreviewerProps>(locale, oProps)
|
|
74
|
+
const builtinDemoUrl = useDemoUrl(props.identifier)
|
|
75
|
+
const demoUrl = props.demoUrl || builtinDemoUrl
|
|
76
|
+
const isActive = history?.location.hash === `#${props.identifier}`
|
|
77
|
+
const isSingleFile = Object.keys(props.sources).length === 1
|
|
78
|
+
const openCSB = useCodeSandbox(props.hideActions?.includes('CSB') ? null : props)
|
|
79
|
+
const openRiddle = useRiddle(props.hideActions?.includes('RIDDLE') ? null : props)
|
|
80
|
+
const [execMotions, isMotionRunning] = useMotions(props.motions || [], demoRef.current)
|
|
81
|
+
const [copyCode, copyStatus] = useCopy()
|
|
82
|
+
const [currentFile, setCurrentFile] = useState('_')
|
|
83
|
+
const [sourceType, setSourceType] = useState(getSourceType(currentFile, props.sources[currentFile]))
|
|
84
|
+
const [showSource, setShowSource] = useState(Boolean(props.defaultShowCode))
|
|
85
|
+
const [iframeKey, setIframeKey] = useState(Math.random())
|
|
86
|
+
const currentFileCode = props.sources[currentFile][sourceType] || props.sources[currentFile].content
|
|
87
|
+
const playgroundUrl = useTSPlaygroundUrl(locale, currentFileCode)
|
|
88
|
+
const iframeRef = useRef<HTMLIFrameElement>()
|
|
89
|
+
const [color] = usePrefersColor()
|
|
90
|
+
|
|
91
|
+
// re-render iframe if prefers color changed
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
setIframeKey(Math.random())
|
|
94
|
+
}, [color])
|
|
95
|
+
|
|
96
|
+
function handleFileChange(filename: string) {
|
|
97
|
+
setCurrentFile(filename)
|
|
98
|
+
setSourceType(getSourceType(filename, props.sources[filename]))
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<div
|
|
103
|
+
style={props.style}
|
|
104
|
+
className={[props.className, '__dumi-default-previewer', isActive ? '__dumi-default-previewer-target' : '']
|
|
105
|
+
.filter(Boolean)
|
|
106
|
+
.join(' ')}
|
|
107
|
+
id={props.identifier}
|
|
108
|
+
data-debug={props.debug || undefined}
|
|
109
|
+
data-iframe={props.iframe || undefined}
|
|
110
|
+
>
|
|
111
|
+
{props.iframe && <div className="__dumi-default-previewer-browser-nav" />}
|
|
112
|
+
<div
|
|
113
|
+
ref={demoRef}
|
|
114
|
+
className="__dumi-default-previewer-demo"
|
|
115
|
+
style={{
|
|
116
|
+
transform: props.transform ? 'translate(0, 0)' : undefined,
|
|
117
|
+
padding: props.compact || (props.iframe && props.compact !== false) ? '0' : undefined,
|
|
118
|
+
background: props.background
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
{props.iframe ? (
|
|
122
|
+
<iframe
|
|
123
|
+
title="dumi-previewer"
|
|
124
|
+
style={{
|
|
125
|
+
// both compatible with unit or non-unit, such as 100, 100px, 100vh
|
|
126
|
+
height: String(props.iframe).replace(/(\d)$/, '$1px')
|
|
127
|
+
}}
|
|
128
|
+
key={iframeKey}
|
|
129
|
+
src={demoUrl}
|
|
130
|
+
ref={iframeRef}
|
|
131
|
+
/>
|
|
132
|
+
) : (
|
|
133
|
+
props.children
|
|
134
|
+
)}
|
|
135
|
+
</div>
|
|
136
|
+
<div className="__dumi-default-previewer-desc" data-title={props.title}>
|
|
137
|
+
{props.title && <AnchorLink to={`#${props.identifier}`}>{props.title}</AnchorLink>}
|
|
138
|
+
{props.description && (
|
|
139
|
+
<div
|
|
140
|
+
// eslint-disable-next-line
|
|
141
|
+
dangerouslySetInnerHTML={{ __html: props.description }}
|
|
142
|
+
/>
|
|
143
|
+
)}
|
|
144
|
+
</div>
|
|
145
|
+
<div className="__dumi-default-previewer-actions">
|
|
146
|
+
{openCSB && (
|
|
147
|
+
<button
|
|
148
|
+
title="Open demo on CodeSandbox.io"
|
|
149
|
+
className="__dumi-default-icon"
|
|
150
|
+
role="codesandbox"
|
|
151
|
+
onClick={openCSB}
|
|
152
|
+
/>
|
|
153
|
+
)}
|
|
154
|
+
{openRiddle && (
|
|
155
|
+
<button title="Open demo on Riddle" className="__dumi-default-icon" role="riddle" onClick={openRiddle} />
|
|
156
|
+
)}
|
|
157
|
+
{props.motions && (
|
|
158
|
+
<button
|
|
159
|
+
title="Execute motions"
|
|
160
|
+
className="__dumi-default-icon"
|
|
161
|
+
role="motions"
|
|
162
|
+
disabled={isMotionRunning}
|
|
163
|
+
onClick={() => execMotions()}
|
|
164
|
+
/>
|
|
165
|
+
)}
|
|
166
|
+
{props.iframe && (
|
|
167
|
+
<button
|
|
168
|
+
title="Reload demo iframe page"
|
|
169
|
+
className="__dumi-default-icon"
|
|
170
|
+
role="refresh"
|
|
171
|
+
onClick={() => setIframeKey(Math.random())}
|
|
172
|
+
/>
|
|
173
|
+
)}
|
|
174
|
+
{!props.hideActions?.includes('EXTERNAL') && (
|
|
175
|
+
<Link target="_blank" to={demoUrl}>
|
|
176
|
+
<button title="Open demo in new tab" className="__dumi-default-icon" role="open-demo" type="button" />
|
|
177
|
+
</Link>
|
|
178
|
+
)}
|
|
179
|
+
<span />
|
|
180
|
+
<button
|
|
181
|
+
title="Copy source code"
|
|
182
|
+
className="__dumi-default-icon"
|
|
183
|
+
role="copy"
|
|
184
|
+
data-status={copyStatus}
|
|
185
|
+
onClick={() => copyCode(currentFileCode)}
|
|
186
|
+
/>
|
|
187
|
+
{sourceType === 'tsx' && showSource && (
|
|
188
|
+
<Link target="_blank" to={playgroundUrl}>
|
|
189
|
+
<button
|
|
190
|
+
title="Get JSX via TypeScript Playground"
|
|
191
|
+
className="__dumi-default-icon"
|
|
192
|
+
role="change-tsx"
|
|
193
|
+
type="button"
|
|
194
|
+
/>
|
|
195
|
+
</Link>
|
|
196
|
+
)}
|
|
197
|
+
<button
|
|
198
|
+
title="Toggle source code panel"
|
|
199
|
+
className={`__dumi-default-icon${showSource ? ' __dumi-default-btn-expand' : ''}`}
|
|
200
|
+
role="source"
|
|
201
|
+
type="button"
|
|
202
|
+
onClick={() => setShowSource(!showSource)}
|
|
203
|
+
/>
|
|
204
|
+
</div>
|
|
205
|
+
{showSource && (
|
|
206
|
+
<div className="__dumi-default-previewer-source-wrapper">
|
|
207
|
+
{!isSingleFile && (
|
|
208
|
+
<Tabs
|
|
209
|
+
className="__dumi-default-previewer-source-tab"
|
|
210
|
+
prefixCls="__dumi-default-tabs"
|
|
211
|
+
moreIcon="···"
|
|
212
|
+
defaultActiveKey={currentFile}
|
|
213
|
+
onChange={handleFileChange}
|
|
214
|
+
>
|
|
215
|
+
{Object.keys(props.sources).map(filename => (
|
|
216
|
+
<TabPane
|
|
217
|
+
tab={filename === '_' ? `index.${getSourceType(filename, props.sources[filename])}` : filename}
|
|
218
|
+
key={filename}
|
|
219
|
+
/>
|
|
220
|
+
))}
|
|
221
|
+
</Tabs>
|
|
222
|
+
)}
|
|
223
|
+
<div className="__dumi-default-previewer-source">
|
|
224
|
+
<SourceCode code={currentFileCode} lang={sourceType} showCopy={false} />
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
)}
|
|
228
|
+
</div>
|
|
229
|
+
)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export default Previewer
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
// import styled from 'styled-components'
|
|
3
|
+
import { Language } from 'prism-react-renderer'
|
|
4
|
+
import Highlight, { defaultProps } from 'prism-react-renderer'
|
|
5
|
+
import { useCopy } from 'dumi/theme'
|
|
6
|
+
import 'prismjs/themes/prism.css'
|
|
7
|
+
import 'dumi-theme-default/src/builtins/SourceCode.less'
|
|
8
|
+
|
|
9
|
+
export interface ICodeBlockProps {
|
|
10
|
+
code: string
|
|
11
|
+
lang: Language
|
|
12
|
+
showCopy?: boolean
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// const Line = styled.div`
|
|
16
|
+
// display: table-row;
|
|
17
|
+
// `
|
|
18
|
+
|
|
19
|
+
// const LineNo = styled.span`
|
|
20
|
+
// display: table-cell;
|
|
21
|
+
// text-align: right;
|
|
22
|
+
// padding-right: 1em;
|
|
23
|
+
// min-width: 4em;
|
|
24
|
+
// user-select: none;
|
|
25
|
+
// opacity: 0.5;
|
|
26
|
+
// `
|
|
27
|
+
|
|
28
|
+
// const LineContent = styled.span`
|
|
29
|
+
// display: table-cell;
|
|
30
|
+
// `
|
|
31
|
+
|
|
32
|
+
export default ({ code, lang, showCopy = true }: ICodeBlockProps) => {
|
|
33
|
+
const [copyCode, copyStatus] = useCopy()
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div className="__dumi-default-code-block">
|
|
37
|
+
<Highlight {...defaultProps} code={code} language={lang} theme={undefined}>
|
|
38
|
+
{({ className, style, tokens, getLineProps, getTokenProps }) => (
|
|
39
|
+
<pre className={className} style={style}>
|
|
40
|
+
{showCopy && (
|
|
41
|
+
<button
|
|
42
|
+
className="__dumi-default-icon __dumi-default-code-block-copy-btn"
|
|
43
|
+
data-status={copyStatus}
|
|
44
|
+
onClick={() => copyCode(code)}
|
|
45
|
+
/>
|
|
46
|
+
)}
|
|
47
|
+
{tokens.map((line, i) => (
|
|
48
|
+
<div {...getLineProps({ line, key: i })}>
|
|
49
|
+
<div key={i} {...getLineProps({ line, key: i })}>
|
|
50
|
+
{/* <div>{i + 1}</div> */}
|
|
51
|
+
<div>
|
|
52
|
+
{line.map((token, key) => (
|
|
53
|
+
<span key={key} {...getTokenProps({ token, key })} />
|
|
54
|
+
))}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
))}
|
|
59
|
+
</pre>
|
|
60
|
+
)}
|
|
61
|
+
</Highlight>
|
|
62
|
+
</div>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { useState, useEffect } from 'react'
|
|
2
|
+
import LZString from 'lz-string'
|
|
3
|
+
import { linkList } from './useTheme'
|
|
4
|
+
|
|
5
|
+
interface IPreviewerComponentProps {
|
|
6
|
+
title?: string
|
|
7
|
+
description?: string
|
|
8
|
+
sources:
|
|
9
|
+
| {
|
|
10
|
+
/**
|
|
11
|
+
* self source code for demo
|
|
12
|
+
* @note jsx exsits definitely, tsx exists when the source code language is tsx
|
|
13
|
+
*/
|
|
14
|
+
_: { jsx: string; tsx?: string }
|
|
15
|
+
}
|
|
16
|
+
| Record<
|
|
17
|
+
string,
|
|
18
|
+
{
|
|
19
|
+
import: string
|
|
20
|
+
content: string
|
|
21
|
+
path?: string
|
|
22
|
+
tsx?: string
|
|
23
|
+
}
|
|
24
|
+
>
|
|
25
|
+
/**
|
|
26
|
+
* third-party dependencies of demo
|
|
27
|
+
*/
|
|
28
|
+
dependencies: any
|
|
29
|
+
/**
|
|
30
|
+
* global identifier for demo
|
|
31
|
+
*/
|
|
32
|
+
identifier: string
|
|
33
|
+
/**
|
|
34
|
+
* the component which demo belongs to
|
|
35
|
+
*/
|
|
36
|
+
componentName?: string
|
|
37
|
+
/**
|
|
38
|
+
* motions of current demo, for snapshot or preview
|
|
39
|
+
*/
|
|
40
|
+
motions?: string[]
|
|
41
|
+
/**
|
|
42
|
+
* mark demo as debug demo, will be discarded in production mode
|
|
43
|
+
*/
|
|
44
|
+
debug?: true
|
|
45
|
+
[key: string]: any
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const CSB_API_ENDPOINT = 'https://codesandbox.io/api/v1/sandboxes/define'
|
|
49
|
+
|
|
50
|
+
// ref: https://github.com/codesandbox/codesandbox-importers/blob/master/packages/import-utils/src/api/define.ts
|
|
51
|
+
function serialize(data: Record<string, any>) {
|
|
52
|
+
return LZString.compressToBase64(JSON.stringify(data))
|
|
53
|
+
.replace(/\+/g, '-') // Convert '+' to '-'
|
|
54
|
+
.replace(/\//g, '_') // Convert '/' to '_'
|
|
55
|
+
.replace(/=+$/, '') // Remove ending '='
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function getTextContent(raw: string) {
|
|
59
|
+
const elm = document.createElement('span')
|
|
60
|
+
|
|
61
|
+
elm.innerHTML = raw
|
|
62
|
+
const text = elm.textContent
|
|
63
|
+
elm.remove()
|
|
64
|
+
|
|
65
|
+
return text
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* get serialized data that use to submit to codesandbox.io
|
|
70
|
+
* @param opts previewer props
|
|
71
|
+
*/
|
|
72
|
+
function getCSBData(opts: IPreviewerComponentProps) {
|
|
73
|
+
const isTSX = Boolean(opts.sources._.tsx)
|
|
74
|
+
const ext = isTSX ? '.tsx' : '.jsx'
|
|
75
|
+
const files: Record<string, { content: string }> = {}
|
|
76
|
+
const deps: Record<string, string> = {}
|
|
77
|
+
const CSSDeps = Object.values(opts.dependencies).filter((dep: any) => dep.css)
|
|
78
|
+
const appFileName = `App${ext}`
|
|
79
|
+
const entryFileName = `index${ext}`
|
|
80
|
+
|
|
81
|
+
// generate dependencies
|
|
82
|
+
Object.entries(opts.dependencies).forEach(([dep, { version }]: any) => {
|
|
83
|
+
deps[dep] = version
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
deps.tslib = '2.3.1'
|
|
87
|
+
|
|
88
|
+
// add react-dom dependency
|
|
89
|
+
if (!deps['react-dom']) {
|
|
90
|
+
deps['react-dom'] = deps.react || 'latest'
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// append sandbox.config.json
|
|
94
|
+
files['sandbox.config.json'] = {
|
|
95
|
+
content: JSON.stringify(
|
|
96
|
+
{
|
|
97
|
+
template: isTSX ? 'create-react-app-typescript' : 'create-react-app'
|
|
98
|
+
},
|
|
99
|
+
null,
|
|
100
|
+
2
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// append package.json
|
|
105
|
+
files['package.json'] = {
|
|
106
|
+
content: JSON.stringify(
|
|
107
|
+
{
|
|
108
|
+
name: opts.title,
|
|
109
|
+
description: getTextContent(opts.description) || 'Amiya Demo',
|
|
110
|
+
main: entryFileName,
|
|
111
|
+
dependencies: deps,
|
|
112
|
+
// add TypeScript dependency if required, must in devDeps to avoid csb compile error
|
|
113
|
+
devDependencies: isTSX ? { typescript: '^3' } : {}
|
|
114
|
+
},
|
|
115
|
+
null,
|
|
116
|
+
2
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
let name = localStorage.getItem('AMIYA_COLOR')
|
|
121
|
+
|
|
122
|
+
if (!name) {
|
|
123
|
+
name = 'default'
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let color = linkList.find(item => item.name === name)
|
|
127
|
+
|
|
128
|
+
let link = color.link
|
|
129
|
+
|
|
130
|
+
// append index.html
|
|
131
|
+
files['index.html'] = {
|
|
132
|
+
content: `<link rel="stylesheet" href="${link}" class="amiya-theme"><div style="margin: 16px;" id="root"></div>`
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// append entry file
|
|
136
|
+
files[entryFileName] = {
|
|
137
|
+
content: `/**
|
|
138
|
+
* This is an auto-generated demo by amiya
|
|
139
|
+
* if you think it is not working as expected,
|
|
140
|
+
* please report the issue at
|
|
141
|
+
* https://github.com/viewweiwu/amiya/issues
|
|
142
|
+
**/
|
|
143
|
+
import React from 'react';
|
|
144
|
+
import ReactDOM from 'react-dom';
|
|
145
|
+
${CSSDeps.map(({ css }: any) => `import '${css}';`).join('\n')}
|
|
146
|
+
import App from './App';
|
|
147
|
+
ReactDOM.render(
|
|
148
|
+
<App />,
|
|
149
|
+
document.getElementById('root'),
|
|
150
|
+
);`
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// append other imported local files
|
|
154
|
+
Object.entries(opts.sources).forEach(([filename, { tsx, jsx, content }]) => {
|
|
155
|
+
// handle primary content
|
|
156
|
+
files[filename === '_' ? appFileName : filename] = {
|
|
157
|
+
content: tsx || jsx || content
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
return serialize({ files })
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* use CodeSandbox.io
|
|
166
|
+
* @param opts previewer opts
|
|
167
|
+
* @note return a open function for open demo on codesandbox.io
|
|
168
|
+
*/
|
|
169
|
+
export default (opts: IPreviewerComponentProps | null, api: string = CSB_API_ENDPOINT) => {
|
|
170
|
+
const [handler, setHandler] = useState<(...args: any) => void | undefined>()
|
|
171
|
+
|
|
172
|
+
useEffect(() => {
|
|
173
|
+
if (opts) {
|
|
174
|
+
const form = document.createElement('form')
|
|
175
|
+
const input = document.createElement('input')
|
|
176
|
+
const data = getCSBData(opts)
|
|
177
|
+
|
|
178
|
+
form.method = 'POST'
|
|
179
|
+
form.target = '_blank'
|
|
180
|
+
form.style.display = 'none'
|
|
181
|
+
form.action = api
|
|
182
|
+
form.appendChild(input)
|
|
183
|
+
form.setAttribute('data-demo', opts.title || '')
|
|
184
|
+
|
|
185
|
+
input.name = 'parameters'
|
|
186
|
+
input.value = data
|
|
187
|
+
|
|
188
|
+
document.body.appendChild(form)
|
|
189
|
+
|
|
190
|
+
setHandler(() => () => form.submit())
|
|
191
|
+
|
|
192
|
+
return () => form.remove()
|
|
193
|
+
}
|
|
194
|
+
}, [opts])
|
|
195
|
+
|
|
196
|
+
return handler
|
|
197
|
+
}
|