-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3d7e0a1
commit 36466f9
Showing
11 changed files
with
498 additions
and
240 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React, { useContext } from 'react'; | ||
import { Context } from './store'; | ||
import { CODE_PREVIEW_PREFIX } from './CodePreview'; | ||
|
||
export interface CodeProps extends React.HTMLAttributes<HTMLDivElement> {} | ||
|
||
export const Code = React.forwardRef<HTMLDivElement, CodeProps>((props, ref) => { | ||
const { className, children, ...htmlProps } = props; | ||
const cls = [`${CODE_PREVIEW_PREFIX}-code`, className].filter(Boolean).join(' ').trim(); | ||
const store = useContext(Context); | ||
if (store.collapse) { | ||
return null; | ||
} | ||
return ( | ||
<div {...htmlProps} className={cls} ref={ref}> | ||
{children} | ||
</div> | ||
); | ||
}); | ||
|
||
Code.displayName = 'uiw.CodeLayoutCode'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import React from 'react'; | ||
import { Code } from './Code'; | ||
import { Preview } from './Preview'; | ||
import { Toolbar } from './Toolbar'; | ||
import { Provider } from './store'; | ||
import './styles.css'; | ||
|
||
export const CODE_PREVIEW_PREFIX = 'w-rcpl'; | ||
|
||
export interface CodePreviewProps extends React.HTMLAttributes<HTMLDivElement> { | ||
prefixCls?: string; | ||
/** | ||
* Whether border is required | ||
* @default true | ||
*/ | ||
bordered?: boolean; | ||
/** disable checkered */ | ||
disableCheckered?: boolean; | ||
} | ||
|
||
const Internal = React.forwardRef<HTMLDivElement, CodePreviewProps>((props, ref) => { | ||
const { | ||
children, | ||
prefixCls = CODE_PREVIEW_PREFIX, | ||
className, | ||
bordered = true, | ||
disableCheckered, | ||
...divProps | ||
} = props; | ||
const cls = [prefixCls, className, bordered ? `w-bordered` : null, disableCheckered ? `w-disable-checkered` : null] | ||
.filter(Boolean) | ||
.join(' ') | ||
.trim(); | ||
return ( | ||
<div ref={ref} {...divProps} className={cls}> | ||
{React.Children.map(children, (child: React.ReactNode, key) => { | ||
if (!React.isValidElement(child)) return child; | ||
return React.cloneElement(child, { ...child.props, key }); | ||
})} | ||
</div> | ||
); | ||
}); | ||
|
||
const InternalCodePreview = (props: CodePreviewProps, ref?: React.ForwardedRef<HTMLDivElement>) => { | ||
return ( | ||
<Provider value={{ collapse: false }}> | ||
<Internal {...props} ref={ref} /> | ||
</Provider> | ||
); | ||
}; | ||
|
||
type CodePreviewComponent = React.FC<React.PropsWithRef<CodePreviewProps>> & { | ||
Preview: typeof Preview; | ||
Code: typeof Code; | ||
Toolbar: typeof Toolbar; | ||
}; | ||
|
||
export const CodePreview: CodePreviewComponent = React.forwardRef<HTMLDivElement>( | ||
InternalCodePreview, | ||
) as unknown as CodePreviewComponent; | ||
|
||
CodePreview.Preview = Preview; | ||
CodePreview.Toolbar = Toolbar; | ||
CodePreview.Code = Code; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from 'react'; | ||
import { CODE_PREVIEW_PREFIX } from './CodePreview'; | ||
|
||
export interface PreviewProps extends React.HTMLAttributes<HTMLDivElement> {} | ||
|
||
export const Preview = React.forwardRef<HTMLDivElement, PreviewProps>((props, ref) => { | ||
const { className, children, ...htmlProps } = props; | ||
const cls = [`${CODE_PREVIEW_PREFIX}-preview`, className].filter(Boolean).join(' ').trim(); | ||
return ( | ||
<div {...htmlProps} className={cls} ref={ref}> | ||
{children} | ||
</div> | ||
); | ||
}); | ||
|
||
Preview.displayName = 'uiw.Preview'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import React, { useContext, useEffect } from 'react'; | ||
import { CODE_PREVIEW_PREFIX } from './CodePreview'; | ||
import { Copied } from './Copied'; | ||
import { ExpandIcon } from './icons'; | ||
import { Context } from './store'; | ||
|
||
export interface ToolbarProps extends React.HTMLAttributes<HTMLDivElement> { | ||
extra?: React.ReactNode; | ||
/** | ||
* Display cope button | ||
* @default true | ||
*/ | ||
copied?: boolean; | ||
/** | ||
* Collapse code display? | ||
* @default true | ||
*/ | ||
collapse?: boolean; | ||
/** | ||
* Display Toolbar? | ||
* @default true | ||
*/ | ||
visible?: boolean; | ||
/** | ||
* Show button or not | ||
* @default true | ||
*/ | ||
visibleButton?: boolean; | ||
/** Code to be copied */ | ||
text?: string; | ||
} | ||
|
||
export const Toolbar = React.forwardRef<HTMLDivElement, ToolbarProps>((props, ref) => { | ||
const { | ||
className, | ||
children, | ||
extra, | ||
text = '', | ||
copied = true, | ||
collapse = true, | ||
visibleButton = true, | ||
visible = true, | ||
...htmlProps | ||
} = props; | ||
const store = useContext(Context); | ||
const cls = [`${CODE_PREVIEW_PREFIX}-toolbar`, className].filter(Boolean).join(' ').trim(); | ||
useEffect(() => store.dispatch!({ collapse }), [collapse]); | ||
if (!visible) { | ||
return null; | ||
} | ||
const handleClick = () => store.dispatch!({ collapse: !store.collapse }); | ||
return ( | ||
<div className={cls} {...htmlProps} ref={ref}> | ||
<div className={`${CODE_PREVIEW_PREFIX}-title`}>{children}</div> | ||
<div className={`${CODE_PREVIEW_PREFIX}-extra`}> | ||
{extra} | ||
{copied && <Copied text={text} />} | ||
{visibleButton && ( | ||
<button onClick={handleClick}> | ||
<ExpandIcon /> | ||
</button> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
}); | ||
|
||
Toolbar.displayName = 'uiw.Toolbar'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,102 +1,4 @@ | ||
import { forwardRef, useState } from 'react'; | ||
import { Copied } from './Copied'; | ||
import { ExpandIcon } from './icons'; | ||
import './styles.css'; | ||
import { CodePreview } from './CodePreview'; | ||
export * from './CodePreview'; | ||
|
||
export interface CodeLayoutProps extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> { | ||
prefixCls?: string; | ||
/** 原始 代码块 渲染 **/ | ||
code?: React.ReactNode; | ||
text?: string; | ||
/** Title section, you can also place buttons **/ | ||
toolbar?: React.ReactNode; | ||
/** 额外内容,展示 toolbar 右侧内容 */ | ||
toolbarExtra?: React.ReactNode; | ||
disableToolbar?: boolean; | ||
disableCode?: boolean; | ||
disablePreview?: boolean; | ||
/** 禁用方格背景 */ | ||
disableCheckered?: boolean; | ||
/** Configure the preview background color. */ | ||
background?: string; | ||
codeProps?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>; | ||
/** | ||
* 是否需要边框 | ||
* @default true | ||
*/ | ||
bordered?: boolean; | ||
/** | ||
* 是否显示复制按钮 | ||
* @default true | ||
*/ | ||
copied?: boolean; | ||
} | ||
|
||
/** react-code-preview-layout 缩写 */ | ||
const PRE_FIX = 'w-rcpl'; | ||
|
||
const CodeLayout = forwardRef<HTMLDivElement, CodeLayoutProps>((props, ref) => { | ||
const [showCode, setShowCode] = useState(false); | ||
const { | ||
children, | ||
toolbar, | ||
bordered = true, | ||
disableCheckered = false, | ||
disablePreview = false, | ||
disableCode = false, | ||
disableToolbar = false, | ||
text = '', | ||
background = '', | ||
copied = true, | ||
toolbarExtra, | ||
code, | ||
prefixCls = PRE_FIX, | ||
className, | ||
codeProps, | ||
...other | ||
} = props; | ||
const cls = [prefixCls, className, bordered ? `w-bordered` : null, disableCheckered ? `w-disable-checkered` : null] | ||
.filter(Boolean) | ||
.join(' ') | ||
.trim(); | ||
|
||
const style: React.CSSProperties = !background | ||
? {} | ||
: { | ||
backgroundColor: background, | ||
backgroundImage: 'none', | ||
}; | ||
return ( | ||
<div ref={ref} {...other} className={cls}> | ||
{!disablePreview && ( | ||
<div className={`${prefixCls}-preview`} style={style}> | ||
{children} | ||
</div> | ||
)} | ||
{!disableToolbar && ( | ||
<div className={`${prefixCls}-toolbar`}> | ||
<div className={`${prefixCls}-title`}>{toolbar}</div> | ||
<div className={`${prefixCls}-extra`}> | ||
{toolbarExtra} | ||
{copied && <Copied text={text} />} | ||
{!disableCode && ( | ||
<button onClick={() => setShowCode(!showCode)}> | ||
<ExpandIcon /> | ||
</button> | ||
)} | ||
</div> | ||
</div> | ||
)} | ||
{!disableCode && !disableToolbar && ( | ||
<div | ||
{...codeProps} | ||
className={`${prefixCls}-code ${codeProps?.className || ''} ${showCode ? 'w-display' : 'w-hidden'}`} | ||
> | ||
{code} | ||
</div> | ||
)} | ||
</div> | ||
); | ||
}); | ||
|
||
export default CodeLayout; | ||
export default CodePreview; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { useReducer, createContext } from 'react'; | ||
|
||
export interface InitialState { | ||
collapse?: boolean; | ||
} | ||
|
||
interface ContextValue extends InitialState { | ||
dispatch?: React.Dispatch<InitialState>; | ||
} | ||
export const initialState: InitialState = {}; | ||
export const Context = createContext<ContextValue>({}); | ||
|
||
export const reducer = (state: InitialState, action: InitialState): InitialState => { | ||
return { ...state, ...action }; | ||
}; | ||
|
||
export const Provider: React.FC<React.PropsWithChildren<{ value?: InitialState }>> = ({ children, value }) => { | ||
const [state, dispatch] = useReducer(reducer, { ...initialState, ...value }); | ||
return <Context.Provider value={{ ...state, dispatch }}>{children}</Context.Provider>; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.