npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@hankliu/rc-mirror-editor

v0.0.2

Published

React easy to use mirror-editor component

Downloads

126

Readme

@hankliu/rc-mirror-editor

NPM version npm download build status Codecov bundle size dumi

Mirror Editor 编辑器是功能齐全的代码编辑器,支持多种常规语言的IDE,允许配置支持智能提示。

特征

  • [x] 支持常见语言
  • [x] 支持多种主题

安装

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('&lt;h1&gt;Hello world&lt;/h1&gt;')
  )</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.