Skip to content

Commit

Permalink
Merge pull request #95 from ant-design/feat/UpgradeHighlight
Browse files Browse the repository at this point in the history
✨ feat: 为 Highlight 组件添加外层 wrapper 模式
  • Loading branch information
rdmclin2 authored Oct 31, 2023
2 parents 293d1b3 + 00876d0 commit 61137b4
Show file tree
Hide file tree
Showing 10 changed files with 1,499 additions and 115 deletions.
11 changes: 6 additions & 5 deletions src/Highlight/components/CopyButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ interface CopyButtonProps {
/**
* @title 复制按钮点击后回调
*/
onCopy: (content: any) => void;
onCopy?: (content: any) => void;
/**
* @title 主题
* @description 主题颜色, dark 黑色主题,light 白色主题
* @default "light"
*/
theme: ThemeType;
prefixCls: string;
theme?: ThemeType;
prefixCls?: string;
style?: React.CSSProperties;
}

const CopyButton: React.FC<CopyButtonProps> = (props) => {
const { content, onCopy, theme, prefixCls } = props;
const { content, onCopy, theme = 'light', prefixCls, style } = props;
const [copyId, setCopyId] = useState<number | undefined>();
const { styles } = useStyles({ prefixCls, theme });

Expand All @@ -44,7 +45,7 @@ const CopyButton: React.FC<CopyButtonProps> = (props) => {
if (onCopy) onCopy(content);
}}
>
<button type={'button'} disabled={copied} className={styles.copy}>
<button type={'button'} disabled={copied} className={styles.copy} style={style}>
<CopyOutlined className={classNames(styles.copyIcon, { scoll: copied })} />
<CheckOutlined className={styles.copyIcon} style={{ color: 'rgb(63,177,99)' }} />
</button>
Expand Down
2 changes: 1 addition & 1 deletion src/Highlight/components/HighLightJS/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
*/
import classNames from 'classnames';
import { useEffect, useState } from 'react';
import { HighlightProps } from '../../defalut';
import { useHighlight } from '../../hooks/useHighlight';
import { HighlightProps } from '../../index';
import { THEME_LIGHT } from '../../theme';
import HighlightCell from '../HighlightCell';
import { useStyles } from './style';
Expand Down
2 changes: 1 addition & 1 deletion src/Highlight/components/HighLighter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import { Loading3QuartersOutlined as Loading } from '@ant-design/icons';
import classNames from 'classnames';
import { Center } from 'react-layout-kit';
import { HighlightProps } from '../../defalut';
import { useShiki } from '../../hooks/useShiki';
import { HighlightProps } from '../../index';
import HighLightJS from '../HighLightJS';
import { useStyles } from './style';

Expand Down
112 changes: 112 additions & 0 deletions src/Highlight/defalut.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import classNames from 'classnames';
import { createRef } from 'react';
import { getPrefixCls } from '../theme';
import CopyButton from './components/CopyButton';
import HighLighter from './components/HighLighter';
import { useKeyDownCopyEvent } from './hooks/useKeyDownCopyEvent';
import { useStyles } from './style';
import { THEME_LIGHT, ThemeType } from './theme';

export interface HighlightProps {
/**
* @description 样式
* @ignore
*/
style?: React.CSSProperties;
/**
* @description className 类名
* @ignore
*/
className?: string;
/**
* @description 类名前缀
* @ignore
*/
prefixCls?: string;
/**
* @title 指定语言
* @description 指定语言
* @renderType select
* @default "typescript"
*/
language: string;
/**
* @title 主题
* @description 主题颜色, dark 黑色主题,light 白色主题
* @default "light"
*/
theme?: ThemeType;
/**
* @title 高亮内容
* @description 高亮内容
*/
children?: any;
/**
* @title 是否使用要使用行号
* @description 是否需要展示代码块左侧的行号
* @default false
*/
lineNumber?: boolean;
/**
* @title 是否展示复制按钮
* @description 是否需要展示复制按钮
* @default true
*/
copyable?: boolean;
/**
* @title 复制按钮点击后回调
*/
onCopy?: (children: any) => void;
/**
* 高亮类型
*/
type?: 'pure' | 'block';
/**
* 是否需要默认外层 wrapper
*/
containerWrapper?: boolean;
}

const HighlightBase: React.FC<HighlightProps> = (props) => {
const {
children,
style,
className,
lineNumber = false,
copyable = true,
theme = THEME_LIGHT,
language,
prefixCls: customPrefixCls,
type = 'block',
onCopy,
} = props;
const prefixCls = getPrefixCls('highlight', customPrefixCls);
const { styles } = useStyles({ prefixCls, theme, type });
const codeRef = createRef<HTMLDivElement>();
useKeyDownCopyEvent(codeRef, onCopy);

return (
<>
<div
ref={codeRef}
tabIndex={-1}
style={style}
className={classNames(styles.container, className)}
>
{copyable && (
<CopyButton prefixCls={prefixCls} onCopy={onCopy} theme={theme} content={children} />
)}
<HighLighter
lineNumber={lineNumber}
language={language}
theme={theme}
prefixCls={prefixCls}
>
{children}
</HighLighter>
</div>
</>
);
};

export { HighlightBase };
39 changes: 39 additions & 0 deletions src/Highlight/demos/wrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* title: wrapper used
*/

import { Highlight } from '@ant-design/pro-editor';
import { Space } from 'antd';

export default () => (
<Space direction="vertical">
<Highlight
language="java"
theme="dark"
containerWrapper
onCopy={(children) => {
console.log('复制代码', children);
}}
>
{`public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}`}
</Highlight>
<Highlight
language="java"
theme="light"
containerWrapper
onCopy={(children) => {
console.log('复制代码', children);
}}
>
{`public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}`}
</Highlight>
</Space>
);
6 changes: 6 additions & 0 deletions src/Highlight/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ group: 基础组件

<code src="./demos/theme.tsx" ></code>

### 外层默认容器包裹

你可以通过 `containerWrapper` 来默认渲染一个外层的容器,改容器提供一些基本能力:展开关闭、语言切换

<code src="./demos/wrapper.tsx" ></code>

## API 参数

### Highlight
Expand Down
114 changes: 8 additions & 106 deletions src/Highlight/index.tsx
Original file line number Diff line number Diff line change
@@ -1,109 +1,11 @@
import classNames from 'classnames';
import { createRef } from 'react';
import { getPrefixCls } from '../theme';
import CopyButton from './components/CopyButton';
import HighLighter from './components/HighLighter';
import { useKeyDownCopyEvent } from './hooks/useKeyDownCopyEvent';
import { useStyles } from './style';
import { THEME_LIGHT, ThemeType } from './theme';

export interface HighlightProps {
/**
* @description 样式
* @ignore
*/
style?: React.CSSProperties;
/**
* @description className 类名
* @ignore
*/
className?: string;
/**
* @description 类名前缀
* @ignore
*/
prefixCls?: string;
/**
* @title 指定语言
* @description 指定语言
* @renderType select
* @default "typescript"
*/
language: string;
/**
* @title 主题
* @description 主题颜色, dark 黑色主题,light 白色主题
* @default "light"
*/
theme?: ThemeType;
/**
* @title 高亮内容
* @description 高亮内容
*/
children?: any;
/**
* @title 是否使用要使用行号
* @description 是否需要展示代码块左侧的行号
* @default false
*/
lineNumber?: boolean;
/**
* @title 是否展示复制按钮
* @description 是否需要展示复制按钮
* @default true
*/
copyable?: boolean;
/**
* @title 复制按钮点击后回调
*/
onCopy?: (children: any) => void;
/**
* 高亮类型
*/
type?: 'pure' | 'block';
}

const Highlight: React.FC<HighlightProps> = (props) => {
const {
children,
style,
className,
lineNumber = false,
copyable = true,
theme = THEME_LIGHT,
language,
prefixCls: customPrefixCls,
type = 'block',
onCopy,
} = props;

const prefixCls = getPrefixCls('highlight', customPrefixCls);
const { styles } = useStyles({ prefixCls, theme, type });
const codeRef = createRef<HTMLDivElement>();
useKeyDownCopyEvent(codeRef, onCopy);

return (
<>
<div
ref={codeRef}
tabIndex={-1}
style={style}
className={classNames(styles.container, className)}
>
{copyable && (
<CopyButton prefixCls={prefixCls} onCopy={onCopy} theme={theme} content={children} />
)}
<HighLighter
lineNumber={lineNumber}
language={language}
theme={theme}
prefixCls={prefixCls}
>
{children}
</HighLighter>
</div>
</>
);
import { HighlightBase, HighlightProps } from './defalut';
import FullFeatureWrapper from './wrapper';

const Highlight = (props: HighlightProps) => {
if (props?.containerWrapper) {
return <FullFeatureWrapper {...props} />;
}
return <HighlightBase {...props} />;
};

export { Highlight };
Loading

0 comments on commit 61137b4

Please sign in to comment.