Skip to content

Commit 7bfc8ce

Browse files
committed
feat: Add toolbarsMode props.
1 parent 071febf commit 7bfc8ce

File tree

7 files changed

+112
-11
lines changed

7 files changed

+112
-11
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ ReactDOM.render(
9393
## Props
9494

9595
- value (*string*) - the raw markdown that will be converted to html (**required**)
96-
- visble (*boolean*) - Shows a preview that will be converted to html.
97-
- toolbars (*array*) - Tool display settings.
96+
- `visble?:boolean` - Shows a preview that will be converted to html.
97+
- `toolbars?:array` - Tool display settings.
98+
- `toolbarsMode?:array` - Tool display settings.
9899
- onChange (*function(editor: IInstance, data: CodeMirror.EditorChange, value: string)*) - called when a change is made (**required**)
99100

100101
> [Other Props Options](https://github.com/uiwjs/react-markdown-editor/blob/8de6abbf628b6d272d7da1c28e985fbbcba71b93/src/components/CodeMirror/index.tsx#L21-L60)

src/common/props.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ export type HTMLDivProps = React.HTMLAttributes<HTMLDivElement>;
77
export interface IProps {
88
className?: string;
99
}
10+
11+
export interface IIconProps {
12+
[key: string]: HTMLElement
13+
}

src/components/Icon/bar.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ export default {
66
<path fill="currentColor" d="M304.793 243.891c33.639-18.537 53.657-54.16 53.657-95.693 0-48.236-26.25-87.626-68.626-104.179C265.138 34.01 240.849 32 209.661 32H24c-8.837 0-16 7.163-16 16v33.049c0 8.837 7.163 16 16 16h33.113v318.53H24c-8.837 0-16 7.163-16 16V464c0 8.837 7.163 16 16 16h195.69c24.203 0 44.834-1.289 66.866-7.584C337.52 457.193 376 410.647 376 350.014c0-52.168-26.573-91.684-71.207-106.123zM142.217 100.809h67.444c16.294 0 27.536 2.019 37.525 6.717 15.828 8.479 24.906 26.502 24.906 49.446 0 35.029-20.32 56.79-53.029 56.79h-76.846V100.809zm112.642 305.475c-10.14 4.056-22.677 4.907-31.409 4.907h-81.233V281.943h84.367c39.645 0 63.057 25.38 63.057 63.057.001 28.425-13.66 52.483-34.782 61.284z" />
77
</svg>
88
),
9+
fullscreen: (
10+
<svg width="16" height="16" viewBox="0 0 1024 1024">
11+
<path fill="currentColor" d="M189.75 428.89a36.87 36.87 0 0 0 36.84-36.85V228.12h164a36.85 36.85 0 1 0 0-73.7H189.75a36.82 36.82 0 0 0-36.8 36.85v200.8a36.83 36.83 0 0 0 36.8 36.82zM834.26 595.06a36.82 36.82 0 0 0-36.8 36.84v164H633.41a36.85 36.85 0 0 0 0 73.7h200.85a36.87 36.87 0 0 0 36.84-36.85V631.9a36.86 36.86 0 0 0-36.84-36.84zM797.46 228.12v179.31a36.82 36.82 0 1 0 73.64 0V191.24a36.86 36.86 0 0 0-36.84-36.85H602.33a36.85 36.85 0 0 0 0 73.7zM421.62 795.9H226.54V616.56a36.82 36.82 0 1 0-73.64 0v216.19a36.83 36.83 0 0 0 36.85 36.85h231.87a36.85 36.85 0 0 0 0-73.7z" />
12+
<path fill="currentColor" d="M306.5 307.94m32.95 0l345.1 0q32.95 0 32.95 32.95l0 342.22q0 32.95-32.95 32.95l-345.1 0q-32.95 0-32.95-32.95l0-342.22q0-32.95 32.95-32.95Z" />
13+
</svg>
14+
),
915
header: (
1016
<svg width="12" height="12" viewBox="0 0 512 512">
1117
<path fill="currentColor" d="M496 80V48c0-8.837-7.163-16-16-16H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.621v128H154.379V96H192c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h37.275v320H32c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.621V288H357.62v128H320c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16h160c8.837 0 16-7.163 16-16v-32c0-8.837-7.163-16-16-16h-37.275V96H480c8.837 0 16-7.163 16-16z" />

src/components/ToolBar/index.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
import classnames from 'classnames';
22
import * as React from "react";
3-
import { HTMLDivProps, IProps } from '../../common/props';
3+
import { IIconProps, IProps } from '../../common/props';
44
import icon from '../Icon/bar';
55
import './index.less';
66

7-
export interface IIconProps {
8-
[key: string]: HTMLElement
9-
}
10-
117
export interface IToolBarProps extends IProps {
128
prefixCls: string,
139
toolbars: string[],
@@ -19,7 +15,7 @@ export default class ToolBar extends React.PureComponent<IToolBarProps, {}> {
1915
public static defaultProps: IToolBarProps = {
2016
onClick: () => null,
2117
prefixCls: 'md-editor',
22-
toolbars: ['bold', 'italic', 'header', 'strike', 'underline', 'olist', 'ulist', 'todo', 'link', 'image', 'quote', 'preview'],
18+
toolbars: ['bold', 'italic', 'header', 'strike', 'underline', 'olist', 'ulist', 'todo', 'link', 'image', 'quote'],
2319
};
2420
public render() {
2521
const { prefixCls, className, onClick, toolbars, ...htmlProps } = this.props;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@editor-prefix:~"md-editor";
2+
3+
:global {
4+
.@{editor-prefix} {
5+
&-toolbar-mode {
6+
float: right;
7+
padding-right: 5px;
8+
.active {
9+
color: #06c;
10+
}
11+
}
12+
}
13+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import classnames from 'classnames';
2+
import * as React from "react";
3+
import { IIconProps, IProps } from '../../common/props';
4+
import icon from '../Icon/bar';
5+
import './index.less';
6+
7+
export interface IToolBarModeProps extends IProps {
8+
prefixCls: string,
9+
toolbarsMode: string[],
10+
onClick: (type: string) => void,
11+
}
12+
13+
export interface IToolBarModeState {
14+
preview: boolean,
15+
fullscreen: boolean,
16+
[key: string]: any,
17+
}
18+
19+
export default class ToolBarMode extends React.PureComponent<IToolBarModeProps, IToolBarModeState, {}> {
20+
public static displayName = 'ToolBar';
21+
public static defaultProps: IToolBarModeProps = {
22+
onClick: () => null,
23+
prefixCls: 'md-editor',
24+
// toolbarsMode: ['preview', 'fullscreen'],
25+
toolbarsMode: ['preview'],
26+
};
27+
constructor(props: IToolBarModeProps) {
28+
super(props);
29+
this.state = {
30+
fullscreen: false,
31+
preview: true,
32+
}
33+
}
34+
35+
public updateMode(key: string, value?: boolean) {
36+
this.setState({ [key]: value });
37+
}
38+
39+
public render() {
40+
const { prefixCls, className, onClick, toolbarsMode, ...htmlProps } = this.props;
41+
const { preview, fullscreen } = this.state;
42+
return (
43+
<div className={classnames(`${prefixCls}-toolbar`, `${prefixCls}-toolbar-mode`, className)} {...htmlProps}>
44+
{toolbarsMode.map((name: string, key) => {
45+
const Icon = (icon as unknown as IIconProps)[name];
46+
return (
47+
<button
48+
key={key}
49+
className={classnames({
50+
active: (preview && name === 'preview') || fullscreen && name === 'fullscreen',
51+
})}
52+
onClick={onClick.bind(this, name)}
53+
>
54+
{Icon}
55+
</button>
56+
);
57+
})}
58+
</div>
59+
);
60+
}
61+
}

src/index.tsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { IProps } from './common/props';
55
import CodeMirror, { ICodeMirror } from './components/CodeMirror';
66
import PreviewMarkdown from './components/PreviewMarkdown';
77
import ToolBar from './components/ToolBar';
8+
import ToolBarMode from './components/ToolBarMode';
89
import './index.less';
910

1011
export interface IMarkdownEditor extends IProps, ICodeMirror {
@@ -13,11 +14,12 @@ export interface IMarkdownEditor extends IProps, ICodeMirror {
1314
height?: number,
1415
visble?: boolean,
1516
toolbars?: string[],
17+
toolbarsMode?: string[],
1618
options?: CodeMirror.EditorConfiguration,
1719
}
1820

1921
interface IMarkdownEditorState {
20-
preview: boolean;
22+
fullscreen: boolean;
2123
}
2224

2325
export default class MarkdownEditor extends React.PureComponent<IMarkdownEditor, IMarkdownEditorState, {}> {
@@ -29,11 +31,13 @@ export default class MarkdownEditor extends React.PureComponent<IMarkdownEditor,
2931
visble: true,
3032
};
3133
public preview!: PreviewMarkdown;
34+
public toolbarsMode!: ToolBarMode;
3235
public CodeMirror!: CodeMirror;
3336
public render() {
34-
const { prefixCls, className, toolbars, onChange, visble, ...codemirrorProps } = this.props;
37+
const { prefixCls, className, toolbars, toolbarsMode, onChange, visble, ...codemirrorProps } = this.props;
3538
return (
3639
<div className={classnames(prefixCls, className)}>
40+
<ToolBarMode ref={(mode: ToolBarMode) => this.toolbarsMode = mode} toolbarsMode={toolbarsMode} onClick={this.onClickMode} />
3741
<ToolBar toolbars={toolbars} onClick={this.onClick} />
3842
<div className={classnames(`${prefixCls}-content`)}>
3943
<CodeMirror
@@ -79,17 +83,33 @@ export default class MarkdownEditor extends React.PureComponent<IMarkdownEditor,
7983
onChange(editor, data, value);
8084
}
8185
}
86+
8287
private previewMarkdown() {
8388
if (this.preview) {
8489
this.preview.state.visble ? this.preview.hide() : this.preview.show();
90+
this.toolbarsMode.updateMode('preview', !this.preview.state.visble);
8591
this.CodeMirror.editor.setSize(this.preview.state.visble ? '100%' : '50%');
8692
}
8793
}
88-
private onClick = (type: string) => {
94+
95+
private fullScreen() {
96+
if (this.toolbarsMode) {
97+
this.toolbarsMode.updateMode('fullscreen', !this.toolbarsMode.state.fullscreen);
98+
}
99+
}
100+
101+
private onClickMode = (type: string) => {
89102
if (type === 'preview') {
90103
this.previewMarkdown();
91104
return;
92105
}
106+
if (type === 'fullscreen') {
107+
this.fullScreen();
108+
return;
109+
}
110+
}
111+
112+
private onClick = (type: string) => {
93113
const selection = this.CodeMirror.editor.getSelection();
94114
const pos = this.CodeMirror.editor.getCursor();
95115
let value = '';

0 commit comments

Comments
 (0)