0.0.2 • Published 21 days ago
@hankliu/rc-mirror-editor v0.0.2
@hankliu/rc-mirror-editor
Mirror Editor
编辑器是功能齐全的代码编辑器,支持多种常规语言的IDE,允许配置支持智能提示。
特征
- 支持常见语言
- 支持多种主题
安装
npm install @hankliu/rc-mirror-editor --save
or
yarn add @hankliu/rc-mirror-editor
or
pnpm install @hankliu/rc-mirror-editor
使用
import type { LanguageName, TMirrorEditorTheme} from '@hankliu/rc-mirror-editor';
import MirrorEditor, { alls, langs } from '@hankliu/rc-mirror-editor';
import { Button, Checkbox, Col, ConfigProvider, Divider, Input, Row, Select } from '@hankliu/hankliu-ui';
import zhCN from '@hankliu/hankliu-ui/lib/locale/zh_CN'
import * as React from 'react';
const LanguageDemo = {
html: `<h1>Turndown Demo</h1>
<p>This demonstrates <a href="https://github.com/mixmark-io/turndown">turndown</a> – an HTML to Markdown converter in JavaScript.</p>
<h2>Usage</h2>
<pre><code class="language-js">var turndownService = new TurndownService()
console.log(
turndownService.turndown('<h1>Hello world</h1>')
)</code></pre>
<hr />
<p>It aims to be <a href="http://commonmark.org/">CommonMark</a>
compliant, and includes options to style the output. These options include:</p>
<ul>
<li>headingStyle (setext or atx)</li>
<li>horizontalRule (*, -, or _)</li>
<li>bullet (*, -, or +)</li>
<li>codeBlockStyle (indented or fenced)</li>
<li>fence (~ or ~)</li>
<li>emDelimiter (_ or *)</li>
<li>strongDelimiter (** or __)</li>
<li>linkStyle (inlined or referenced)</li>
<li>linkReferenceStyle (full, collapsed, or shortcut)</li>
</ul>
`,
};
const themeOptions = ['dark', 'light']
.concat(Object.keys(alls))
.filter((item) => typeof alls[item as keyof typeof alls] !== 'function')
.filter((item) => !/^(defaultSettings)/.test(item as keyof typeof alls));
const heightOptions = ['auto', '200px', '300px', '500px'];
export default function Base() {
const [content, setContent] = React.useState<string>(LanguageDemo.html);
const [language, setLanguage] = React.useState<LanguageName>("html");
const [theme, setTheme] = React.useState<TMirrorEditorTheme>('dark');
const [height, setHeight] = React.useState<string>('500px');
const [placeholder, setPlaceholder] = React.useState<string>('请输入内容');
const [autofocus, setAutofocus] = React.useState<boolean>(false);
const [editable, setEditable] = React.useState<boolean>(true);
const onDidChangeTheme = (callback: (theme: "dark" | "light") => void) => {
const root = document.querySelector("html");
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === "attributes") {
if (root?.getAttribute("data-prefers-color") === "dark") {
callback("dark");
} else {
callback("light");
}
}
}
});
observer.observe(root, { attributes: true });
return () => {
observer.disconnect();
};
}
return (
<ConfigProvider locale={zhCN}>
<MirrorEditor
editable={editable}
autoFocus={autofocus}
placeholder={placeholder}
height={height}
value={content}
language={language}
theme={theme}
onChange={(val) => {
setContent(val);
}}
getWebAppTheme={() => {
return document.querySelector("html")?.getAttribute("data-prefers-color") === "dark"
? "dark"
: "light";
}}
onWebAppThemeChange={onDidChangeTheme}
/>
<Divider />
<Row gutter={16}>
<Col span={8}>
<Row align="middle">
<Col flex="80px">语言:</Col>
<Col flex="1">
<Select
value={language}
style={{ width: "100%" }}
onChange={(val) => {
setContent(LanguageDemo[val] || '');
setLanguage(val);
}}
showSearch
>
{
Object.keys(langs).sort().map((item) => (
<Select.Option key={item} value={item}>{item}</Select.Option>
))
}
</Select>
</Col>
</Row>
</Col>
<Col span={8}>
<Row align="middle">
<Col flex="80px">主题:</Col>
<Col flex="1">
<Select
value={theme}
style={{ width: "100%" }}
onChange={(val) => {
setTheme(val);
}}
showSearch
>
{
themeOptions.map((item) => (
<Select.Option key={item} value={item}>{item}</Select.Option>
))
}
</Select>
</Col>
</Row>
</Col>
<Col span={8}>
<Row align="middle">
<Col flex="80px">高度:</Col>
<Col flex="1">
<Select
value={height}
style={{ width: "100%" }}
onChange={(val) => {
setHeight(val);
}}
showSearch
>
{
heightOptions.map((item) => (
<Select.Option key={item} value={item}>{item}</Select.Option>
))
}
</Select>
</Col>
</Row>
</Col>
</Row>
<Row gutter={16} style={{ marginTop: '16px' }}>
<Col span={8}>
<Row align="middle">
<Col flex="80px">placeholder:</Col>
<Col flex="1">
<Input
style={{ width: "100" }}
value={placeholder}
onChange={(event) => { setPlaceholder(event.target.value) }}
/>
</Col>
</Row>
</Col>
<Col span={8}>
<Row align="middle">
<Col flex="80px">自动聚焦:</Col>
<Col flex="1">
<Checkbox
checked={autofocus}
onChange={(event) => { setAutofocus(event.target.checked) }}
>
自动聚焦
</Checkbox>
</Col>
</Row>
</Col>
<Col span={8}>
<Row align="middle">
<Col flex="80px">是否可编辑:</Col>
<Col flex="1">
<Checkbox
checked={editable}
onChange={(event) => { setEditable(event.target.checked) }}
>
可编辑
</Checkbox>
</Col>
</Row>
</Col>
</Row>
<Row gutter={16} style={{ marginTop: '16px' }}>
<Col span={8}>
<Button onClick={() => { setContent('') }}>清空内容</Button>
</Col>
</Row>
</ConfigProvider>
);
}
API 参数
名称 | 类型 | 默认值 | 描述 |
---|---|---|---|
className | string | - | 组件外层元素classname |
prefixCls | string | hlui-mirror-editor | 组件外层元素 classname 前缀 |
width | string | number | 100% | 编辑器的宽度。 |
minWidth | string | number | auto | 编辑器的最小宽度。 |
maxWidth | string | number | auto | 编辑器的最大宽度。 |
height | string | number | 100% | 编辑器的高度 |
minHeight | string | number | auto | 编辑器的最小高度 |
maxHeight | string | number | auto | 编辑器的最大高度 |
value | 编辑器中自动创建的模型的值 | string | - |
language | string | html | 编辑器中自动创建的模型的初始语言 |
theme | TMirrorEditorTheme | - | 编辑器的主题 |
options | EditorStateConfig | 默认值在如下所示 | 请参阅 EditorStateConfig |
placeholder | string | HTMLElement | - | 编辑器中占位符 |
indentWithTab | boolean | true | 是否使用制表符缩进 |
readOnly | boolean | false | 编辑器是否只读 |
editable | boolean | true | 编辑器是否允许编辑 |
autoFocus | boolean | true | 编辑器是否自动聚焦 |
basicSetup | boolean | BasicSetupOptions | true | 编辑器中是否进行初始化配置 |
highlightWhitespace | boolean | true | 是否高亮空格 |
highlightActiveLine | boolean | true | 是否高亮当前所在的行 |
onChange | (newValue: string, event: ViewUpdate) => void | - | 当前编辑器模型的内容发生更改时发出的事件 |
onWillMount | (state: EditorState) => void | - | 在编辑器挂载之前发出的事件(类似于 componentWillMount React ) |
onMount | (editor: EditorView, state: EditorState) => void | - | 挂载编辑器时发出的事件(类似于 componentDidMount React ) |
onWillUnmount | (editor: EditorView, state: EditorState) => void | - | 在编辑器卸载之前发出的事件(类似于 componentWillUnmount React ) |
getWebAppTheme | () => "dark" | "light" | getTheme | 获得当前Web应用的主题模式(亮色|暗色),当不存在 theme 参数时根据当前函数的返回值设置编辑器的主题 |
onWebAppThemeChange | (callback: (theme: "dark" | "light") => void) => (() => void) | void | onDidChangeTheme | 当当前Web应用的主题模式(亮色|暗色)发生改变时的监听函数,当不存在 theme 参数时根据当前监听函数的返回值动态设置编辑器的主题 |
案例
npm start
然后打开 http://localhost:8000/examples/
线上案例: https://hankliu62.github.io/rc-mirror-editor
单元测试
npm test
覆盖率
npm run coverage
License
@hankliu/rc-mirror-editor is released under the MIT license.