diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96aea41e5..a51ff8637 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,22 +8,30 @@ jobs: build-deploy: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: - node-version: 14 + node-version: 16 - run: npm install - - run: npm run doc - - run: npm run map - - run: npm run bundle - - run: npm run bundle:min - - run: npm run coverage + - working-directory: core + run: | + npm run build + npm run bundle + npm run bundle:min + npm run coverage + + - working-directory: www + run: | + npm run build + npm run map + + - run: cp -rp core/coverage ./ - name: Create Coverage Badges uses: jaywcjlove/coverage-badges-cli@main - - run: npm run doc + - run: cp -rp www/build ./ - run: cp -rp coverage build - name: Generate Contributors Images @@ -37,11 +45,11 @@ jobs: id: create_tag uses: jaywcjlove/create-tag-action@v1.3.6 with: - package-path: ./package.json + package-path: ./core/package.json - name: get tag version id: tag_version - uses: jaywcjlove/changelog-generator@v1.5.0 + uses: jaywcjlove/changelog-generator@v1.5.3 - name: Deploy uses: peaceiris/actions-gh-pages@v3 @@ -55,7 +63,7 @@ jobs: - name: Generate Changelog id: changelog - uses: jaywcjlove/changelog-generator@v1.5.0 + uses: jaywcjlove/changelog-generator@v1.5.3 with: head-ref: ${{steps.create_tag.outputs.version}} filter-author: (renovate-bot|Renovate Bot) @@ -64,7 +72,7 @@ jobs: - name: Create Release uses: jaywcjlove/create-tag-action@v1.3.6 with: - package-path: ./package.json + package-path: ./core/package.json release: true body: | [![](https://img.shields.io/badge/Open%20in-unpkg-blue)](https://uiwjs.github.io/npm-unpkg/#/pkg/@uiw/react-md-editor@${{steps.changelog.outputs.version}}/file/README.md) @@ -82,5 +90,5 @@ jobs: uses: JS-DevTools/npm-publish@v1 with: token: ${{ secrets.NPM_TOKEN }} - package: ./package.json + package: ./core/package.json diff --git a/.kktrc.ts b/.kktrc.ts deleted file mode 100644 index 178900503..000000000 --- a/.kktrc.ts +++ /dev/null @@ -1,75 +0,0 @@ -import path from 'path'; -import webpack, { Configuration } from 'webpack'; -import { LoaderConfOptions } from 'kkt'; -import lessModules from '@kkt/less-modules'; -import rawModules from '@kkt/raw-modules'; -import scopePluginOptions from '@kkt/scope-plugin-options'; -import pkg from './package.json'; - -export default (conf: Configuration, env: 'production' | 'development', options: LoaderConfOptions) => { - conf = lessModules(conf, env, options); - if (options.bundle) { - conf.output!.library = '@uiw/react-md-editor'; - conf.externals = { - react: { - root: 'React', - commonjs2: 'react', - commonjs: 'react', - amd: 'react', - }, - }; - } else { - conf = rawModules(conf, env, { ...options }); - conf = scopePluginOptions(conf, env, { - ...options, - allowedFiles: [path.resolve(process.cwd(), 'README.md')], - }); - // Get the project version. - conf.plugins!.push( - new webpack.DefinePlugin({ - VERSION: JSON.stringify(pkg.version), - }), - ); - if (env === 'production') { - conf.optimization = { - ...conf.optimization, - splitChunks: { - cacheGroups: { - reactvendor: { - test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/, - name: 'react-vendor', - chunks: 'all', - }, - katex: { - test: /[\\/]node_modules[\\/](katex)[\\/]/, - name: 'katex-vendor', - chunks: 'async', - }, - micromark: { - test: /[\\/]node_modules[\\/](micromark)[\\/]/, - name: 'micromark-vendor', - chunks: 'all', - }, - prismjs: { - test: /[\\/]node_modules[\\/](refractor)[\\/]/, - name: 'refractor-prismjs-vendor', - chunks: 'all', - }, - runtime: { - test: /[\\/]node_modules[\\/](@babel[\\/]runtime)[\\/]/, - name: 'babel-runtime-vendor', - chunks: 'all', - }, - parse5: { - test: /[\\/]node_modules[\\/](parse5)[\\/]/, - name: 'parse5-vendor', - chunks: 'all', - }, - }, - }, - }; - conf.output = { ...conf.output, publicPath: './' }; - } - } - return conf; -}; diff --git a/core/.kktrc.ts b/core/.kktrc.ts new file mode 100644 index 000000000..2b0e851d3 --- /dev/null +++ b/core/.kktrc.ts @@ -0,0 +1,22 @@ +// import path from 'path'; +import { Configuration } from 'webpack'; +import { LoaderConfOptions } from 'kkt'; +import lessModules from '@kkt/less-modules'; +// import rawModules from '@kkt/raw-modules'; +// import pkg from './package.json'; + +export default (conf: Configuration, env: 'production' | 'development', options: LoaderConfOptions) => { + conf = lessModules(conf, env, options); + if (options.bundle) { + conf.output!.library = '@uiw/react-md-editor'; + conf.externals = { + react: { + root: 'React', + commonjs2: 'react', + commonjs: 'react', + amd: 'react', + }, + }; + } + return conf; +}; diff --git a/README.md b/core/README.md similarity index 95% rename from README.md rename to core/README.md index cf44bfad5..8b3bb8639 100644 --- a/README.md +++ b/core/README.md @@ -58,7 +58,7 @@ npm i @uiw/react-md-editor [![Open in Github gh-pages](https://img.shields.io/badge/Open%20In-Github%20gh--pages-blue?logo=github)](https://uiwjs.github.io/react-md-editor/) [![Open in Gitee gh-pages](https://img.shields.io/badge/Open%20In-Gitee%20gh--pages-blue?logo=web)](https://uiw.gitee.io/react-md-editor/) -```jsx +```jsx mdx:preview import React from "react"; import MDEditor from '@uiw/react-md-editor'; @@ -70,7 +70,7 @@ export default function App() { value={value} onChange={setValue} /> - + ); } @@ -81,13 +81,13 @@ export default function App() { Please note markdown needs to be sanitized if you do not **completely trust** your authors. Otherwise, your app is vulnerable to XSS. This can be achieved by adding [rehype-sanitize](https://github.com/rehypejs/rehype-sanitize) as a plugin. -```jsx +```jsx mdx:preview import React from "react"; import MDEditor from '@uiw/react-md-editor'; import rehypeSanitize from "rehype-sanitize"; export default function App() { - const [value, setValue] = React.useState("**Hello world!!!** "); + const [value, setValue] = React.useState(`**Hello world!!!** `); return (
-
); } @@ -110,12 +106,11 @@ export default function App() { [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/embed/react-md-editor-custom-toolbars-m2n10?fontsize=14&hidenavigation=1&theme=dark) -```tsx +```jsx mdx:preview import React from "react"; -import ReactDOM from "react-dom"; -import MDEditor, { commands, ICommand, TextState, TextAreaTextApi } from '@uiw/react-md-editor'; +import MDEditor, { commands } from '@uiw/react-md-editor'; -const title3: ICommand = { +const title3 = { name: 'title3', keyCommand: 'title3', buttonProps: { 'aria-label': 'Insert title3' }, @@ -124,7 +119,7 @@ const title3: ICommand = { ), - execute: (state: TextState, api: TextAreaTextApi) => { + execute: (state, api) => { let modifyText = `### ${state.selectedText}\n`; if (!state.selectedText) { modifyText = `### `; @@ -134,14 +129,12 @@ const title3: ICommand = { }; export default function App() { - const [value, setValue] = React.useState("**Hello world!!!**"); + const [value, setValue] = React.useState("Hello Markdown! `Tab` key uses default behavior"); return (
{ - setValue(val!); - }} + value={value} + onChange={setValue} commands={[ // Custom Toolbars title3, @@ -163,13 +156,13 @@ export default function App() { return (
My Custom Toolbar
- +
); }, - execute: (state: TextState, api: TextAreaTextApi) => { + execute: (state, api) => { console.log('>>>>>>update>>>>>', state) }, buttonProps: { 'aria-label': 'Insert title'} @@ -185,7 +178,7 @@ export default function App() { [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/embed/react-md-editor-preview-markdown-vrucl?fontsize=14&hidenavigation=1&theme=dark) -```jsx +```jsx mdx:preview import React from "react"; import ReactDOM from "react-dom"; import MDEditor from '@uiw/react-md-editor'; @@ -213,7 +206,7 @@ The following example is preview in [CodeSandbox](https://codesandbox.io/s/markd npm install katex ``` -```jsx +```jsx mdx:preview import React from "react"; import ReactDOM from "react-dom"; import MDEditor from '@uiw/react-md-editor'; @@ -271,7 +264,7 @@ export default function App() { [![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?logo=codesandbox)](https://codesandbox.io/embed/react-md-editor-text-to-images-ijqmx?fontsize=14&hidenavigation=1&theme=dark) -```jsx +```tsx mdx:preview import React from "react"; import MDEditor, { commands, ICommand, TextState, TextAreaTextApi } from "@uiw/react-md-editor"; import domToImage from "dom-to-image"; @@ -286,7 +279,7 @@ const textToImage: ICommand = { ), execute: (state: TextState, api: TextAreaTextApi) => { - const dom = document.getElementsByClassName("w-md-editor")[0]; + const dom = document.getElementsByClassName("gooooooooo")[0]; if (dom) { domToImage.toJpeg(dom, {}).then((dataUrl) => { const link = document.createElement("a"); @@ -302,6 +295,7 @@ export default function App() { return (
>John: Jolly good! `; const randomid = () => parseInt(String(Math.random() * 1e15), 10).toString(36); -const Code = ({ inline, children = [], className, ...props }: any) => { +const Code = ({ inline, children = [], className, ...props }) => { const demoid = useRef(`dome${randomid()}`); const code = getCode(children); const demo = useRef(null); diff --git a/core/package.json b/core/package.json new file mode 100644 index 000000000..041bf2cd9 --- /dev/null +++ b/core/package.json @@ -0,0 +1,61 @@ +{ + "name": "@uiw/react-md-editor", + "version": "3.14.1", + "description": "A markdown editor with preview, implemented with React.js and TypeScript.", + "homepage": "https://uiwjs.github.io/react-md-editor/", + "author": "kenny wang ", + "main": "lib/index.js", + "module": "esm/index.js", + "scripts": { + "css:build": "compile-less -d src -o esm", + "css:watch": "compile-less -d src -o esm --watch", + "css:build:dist": "compile-less -d src --combine markdown-editor.css --rm-global", + "bundle": "ncc build src/index.tsx --target web --filename mdeditor", + "bundle:watch": "ncc watch src/index.tsx --target web --filename mdeditor", + "bundle:min": "ncc build src/index.tsx --target web --filename mdeditor --minify", + "watch": "tsbb watch & npm run css:watch", + "build": "tsbb build && npm run css:build && npm run css:build:dist", + "test": "tsbb test --env=jsdom", + "coverage": "tsbb test --env=jsdom --coverage --bail" + }, + "repository": { + "type": "git", + "url": "https://github.com/uiwjs/react-md-editor" + }, + "files": [ + "markdown-editor.css", + "lib", + "dist", + "esm", + "src" + ], + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + }, + "dependencies": { + "@babel/runtime": "^7.14.6", + "@uiw/react-markdown-preview": "^4.0.10", + "rehype": "~12.0.1" + }, + "keywords": [ + "react", + "editor", + "md-editor", + "markdown", + "react-markdown", + "react-md-editor", + "react-markdown-editor", + "markdown-editor", + "md", + "uiw", + "uiwjs", + "code" + ], + "jest": { + "transformIgnorePatterns": [ + "/node_modules/?!(.*)" + ] + } +} \ No newline at end of file diff --git a/src/Context.tsx b/core/src/Context.tsx similarity index 100% rename from src/Context.tsx rename to core/src/Context.tsx diff --git a/src/Editor.tsx b/core/src/Editor.tsx similarity index 100% rename from src/Editor.tsx rename to core/src/Editor.tsx diff --git a/src/__test__/commands.test.tsx b/core/src/__test__/commands.test.tsx similarity index 100% rename from src/__test__/commands.test.tsx rename to core/src/__test__/commands.test.tsx diff --git a/src/__test__/editor.test.tsx b/core/src/__test__/editor.test.tsx similarity index 100% rename from src/__test__/editor.test.tsx rename to core/src/__test__/editor.test.tsx diff --git a/src/__test__/utils/getSurroundingWord.test.tsx b/core/src/__test__/utils/getSurroundingWord.test.tsx similarity index 100% rename from src/__test__/utils/getSurroundingWord.test.tsx rename to core/src/__test__/utils/getSurroundingWord.test.tsx diff --git a/src/commands/bold.tsx b/core/src/commands/bold.tsx similarity index 98% rename from src/commands/bold.tsx rename to core/src/commands/bold.tsx index c19bfce57..82a9b0d75 100644 --- a/src/commands/bold.tsx +++ b/core/src/commands/bold.tsx @@ -1,4 +1,4 @@ -import * as React from 'react'; +import React from 'react'; import { ICommand, TextState, TextAreaTextApi } from './'; import { selectWord } from '../utils/markdownUtils'; diff --git a/src/commands/code.tsx b/core/src/commands/code.tsx similarity index 100% rename from src/commands/code.tsx rename to core/src/commands/code.tsx diff --git a/src/commands/comment.tsx b/core/src/commands/comment.tsx similarity index 100% rename from src/commands/comment.tsx rename to core/src/commands/comment.tsx diff --git a/src/commands/divider.tsx b/core/src/commands/divider.tsx similarity index 100% rename from src/commands/divider.tsx rename to core/src/commands/divider.tsx diff --git a/src/commands/fullscreen.tsx b/core/src/commands/fullscreen.tsx similarity index 100% rename from src/commands/fullscreen.tsx rename to core/src/commands/fullscreen.tsx diff --git a/src/commands/group.tsx b/core/src/commands/group.tsx similarity index 100% rename from src/commands/group.tsx rename to core/src/commands/group.tsx diff --git a/src/commands/hr.tsx b/core/src/commands/hr.tsx similarity index 100% rename from src/commands/hr.tsx rename to core/src/commands/hr.tsx diff --git a/src/commands/image.tsx b/core/src/commands/image.tsx similarity index 100% rename from src/commands/image.tsx rename to core/src/commands/image.tsx diff --git a/src/commands/index.ts b/core/src/commands/index.ts similarity index 100% rename from src/commands/index.ts rename to core/src/commands/index.ts diff --git a/src/commands/italic.tsx b/core/src/commands/italic.tsx similarity index 100% rename from src/commands/italic.tsx rename to core/src/commands/italic.tsx diff --git a/src/commands/link.tsx b/core/src/commands/link.tsx similarity index 100% rename from src/commands/link.tsx rename to core/src/commands/link.tsx diff --git a/src/commands/list.tsx b/core/src/commands/list.tsx similarity index 100% rename from src/commands/list.tsx rename to core/src/commands/list.tsx diff --git a/src/commands/preview.tsx b/core/src/commands/preview.tsx similarity index 100% rename from src/commands/preview.tsx rename to core/src/commands/preview.tsx diff --git a/src/commands/quote.tsx b/core/src/commands/quote.tsx similarity index 100% rename from src/commands/quote.tsx rename to core/src/commands/quote.tsx diff --git a/src/commands/strikeThrough.tsx b/core/src/commands/strikeThrough.tsx similarity index 100% rename from src/commands/strikeThrough.tsx rename to core/src/commands/strikeThrough.tsx diff --git a/src/commands/title.tsx b/core/src/commands/title.tsx similarity index 100% rename from src/commands/title.tsx rename to core/src/commands/title.tsx diff --git a/src/commands/title1.tsx b/core/src/commands/title1.tsx similarity index 100% rename from src/commands/title1.tsx rename to core/src/commands/title1.tsx diff --git a/src/commands/title2.tsx b/core/src/commands/title2.tsx similarity index 100% rename from src/commands/title2.tsx rename to core/src/commands/title2.tsx diff --git a/src/commands/title3.tsx b/core/src/commands/title3.tsx similarity index 100% rename from src/commands/title3.tsx rename to core/src/commands/title3.tsx diff --git a/src/commands/title4.tsx b/core/src/commands/title4.tsx similarity index 100% rename from src/commands/title4.tsx rename to core/src/commands/title4.tsx diff --git a/src/commands/title5.tsx b/core/src/commands/title5.tsx similarity index 100% rename from src/commands/title5.tsx rename to core/src/commands/title5.tsx diff --git a/src/commands/title6.tsx b/core/src/commands/title6.tsx similarity index 100% rename from src/commands/title6.tsx rename to core/src/commands/title6.tsx diff --git a/src/components/DragBar/index.less b/core/src/components/DragBar/index.less similarity index 100% rename from src/components/DragBar/index.less rename to core/src/components/DragBar/index.less diff --git a/src/components/DragBar/index.tsx b/core/src/components/DragBar/index.tsx similarity index 100% rename from src/components/DragBar/index.tsx rename to core/src/components/DragBar/index.tsx diff --git a/src/components/TextArea/Markdown.tsx b/core/src/components/TextArea/Markdown.tsx similarity index 100% rename from src/components/TextArea/Markdown.tsx rename to core/src/components/TextArea/Markdown.tsx diff --git a/src/components/TextArea/Textarea.tsx b/core/src/components/TextArea/Textarea.tsx similarity index 100% rename from src/components/TextArea/Textarea.tsx rename to core/src/components/TextArea/Textarea.tsx diff --git a/src/components/TextArea/handleKeyDown.tsx b/core/src/components/TextArea/handleKeyDown.tsx similarity index 100% rename from src/components/TextArea/handleKeyDown.tsx rename to core/src/components/TextArea/handleKeyDown.tsx diff --git a/src/components/TextArea/index.less b/core/src/components/TextArea/index.less similarity index 100% rename from src/components/TextArea/index.less rename to core/src/components/TextArea/index.less diff --git a/src/components/TextArea/index.tsx b/core/src/components/TextArea/index.tsx similarity index 100% rename from src/components/TextArea/index.tsx rename to core/src/components/TextArea/index.tsx diff --git a/src/components/TextArea/shortcuts.ts b/core/src/components/TextArea/shortcuts.ts similarity index 100% rename from src/components/TextArea/shortcuts.ts rename to core/src/components/TextArea/shortcuts.ts diff --git a/src/components/Toolbar/Child.less b/core/src/components/Toolbar/Child.less similarity index 100% rename from src/components/Toolbar/Child.less rename to core/src/components/Toolbar/Child.less diff --git a/src/components/Toolbar/Child.tsx b/core/src/components/Toolbar/Child.tsx similarity index 100% rename from src/components/Toolbar/Child.tsx rename to core/src/components/Toolbar/Child.tsx diff --git a/src/components/Toolbar/index.less b/core/src/components/Toolbar/index.less similarity index 100% rename from src/components/Toolbar/index.less rename to core/src/components/Toolbar/index.less diff --git a/src/components/Toolbar/index.tsx b/core/src/components/Toolbar/index.tsx similarity index 100% rename from src/components/Toolbar/index.tsx rename to core/src/components/Toolbar/index.tsx diff --git a/src/index.less b/core/src/index.less similarity index 89% rename from src/index.less rename to core/src/index.less index 838cdad2d..6a6cde51b 100644 --- a/src/index.less +++ b/core/src/index.less @@ -22,6 +22,10 @@ width: 50%; height: 100%; } + &-text-pre > code { + word-break: break-word !important; + white-space: pre-wrap !important; + } &-preview { width: 50%; box-sizing: border-box; @@ -35,6 +39,8 @@ border-radius: 0 0 5px 0; display: flex; flex-direction: column; + // word-break: break-word !important; + // white-space: pre-wrap !important; .anchor { display: none; } diff --git a/src/index.tsx b/core/src/index.tsx similarity index 100% rename from src/index.tsx rename to core/src/index.tsx diff --git a/src/react-app-env.d.ts b/core/src/react-app-env.d.ts similarity index 100% rename from src/react-app-env.d.ts rename to core/src/react-app-env.d.ts diff --git a/src/utils/InsertTextAtPosition.ts b/core/src/utils/InsertTextAtPosition.ts similarity index 100% rename from src/utils/InsertTextAtPosition.ts rename to core/src/utils/InsertTextAtPosition.ts diff --git a/src/utils/markdownUtils.ts b/core/src/utils/markdownUtils.ts similarity index 100% rename from src/utils/markdownUtils.ts rename to core/src/utils/markdownUtils.ts diff --git a/website/tsconfig.json b/core/tsconfig.json similarity index 56% rename from website/tsconfig.json rename to core/tsconfig.json index 1f3eb31aa..d45acebb4 100644 --- a/website/tsconfig.json +++ b/core/tsconfig.json @@ -1,10 +1,9 @@ { "extends": "../tsconfig", - "include": ["../src"], + "include": ["src", ".kktrc.ts"], "compilerOptions": { "baseUrl": ".", "emitDeclarationOnly": true, - "noEmit": false, - "typeRoots": ["./react-app-env.d.ts"] + "noEmit": false } } diff --git a/lerna.json b/lerna.json new file mode 100644 index 000000000..67cdb6849 --- /dev/null +++ b/lerna.json @@ -0,0 +1,5 @@ +{ + "version": "3.14.1", + "packages": ["core", "www"], + "useWorkspaces": true +} diff --git a/package.json b/package.json index 324454747..fe71f2ce6 100644 --- a/package.json +++ b/package.json @@ -1,75 +1,49 @@ { - "name": "@uiw/react-md-editor", - "version": "3.14.1", - "description": "A markdown editor with preview, implemented with React.js and TypeScript.", - "homepage": "https://uiwjs.github.io/react-md-editor/", - "author": "kenny wang ", - "main": "lib/index.js", - "module": "esm/index.js", + "private": true, "scripts": { - "prepare": "husky install && npm run build", - "released": "npm run build && npm run doc", - "doc": "kkt build --app-src ./website", - "start": "kkt start --app-src ./website", - "css:build": "compile-less -d src -o esm", - "css:watch": "compile-less -d src -o esm --watch", - "css:build:dist": "compile-less -d src --combine markdown-editor.css --rm-global", - "bundle": "ncc build src/index.tsx --target web --filename mdeditor", - "bundle:watch": "ncc watch src/index.tsx --target web --filename mdeditor", - "bundle:min": "ncc build src/index.tsx --target web --filename mdeditor --minify", - "watch": "tsbb watch & npm run css:watch", - "build": "tsbb build && npm run css:build && npm run css:build:dist", - "test": "tsbb test --env=jsdom", - "coverage": "tsbb test --env=jsdom --coverage --bail", + "⬇️⬇️⬇️⬇️⬇️ package ⬇️⬇️⬇️⬇️⬇️": "▼▼▼▼▼ package ▼▼▼▼▼", + "watch": "npm run-script watch --workspace @uiw/react-md-editor", + "build": "npm run-script build --workspace @uiw/react-md-editor", + "doc": "npm run-script build --workspace www", + "start": "npm run-script start --workspace www", + "⬆️⬆️⬆️⬆️⬆️ package ⬆️⬆️⬆️⬆️⬆️": "▲▲▲▲▲ package ▲▲▲▲▲", + "prepare": "husky install", + "version": "lerna version --exact --force-publish --no-push --no-git-tag-version", "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", - "map": "source-map-explorer build/static/js/*.js --html build/website-result.html" + "remove": "npm run clean && lerna exec \"rm -rf package-lock.json\" --scope react-code-preview-layout --scope website", + "clean": "lerna clean --yes" }, "repository": { "type": "git", "url": "https://github.com/uiwjs/react-md-editor" }, - "files": [ - "markdown-editor.css", - "lib", - "dist", - "esm", - "src" - ], "license": "MIT", - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - }, "devDependencies": { "@kkt/less-modules": "~7.1.1", "@kkt/ncc": "~1.0.9", - "@kkt/raw-modules": "~7.1.1", - "@kkt/scope-plugin-options": "~7.1.1", - "@types/katex": "~0.14.0", - "@types/react": "~18.0.9", - "@types/react-dom": "~18.0.3", "@types/react-test-renderer": "~18.0.0", - "@uiw/react-github-corners": "~1.5.3", - "@uiw/react-shields": "~1.1.2", - "@wcj/dark-mode": "~1.0.9", "compile-less-cli": "~1.8.13", - "katex": "~0.15.2", "husky": "~8.0.0", "kkt": "~7.1.5", "lint-staged": "~12.4.0", - "mermaid": "~8.14.0", "prettier": "~2.6.0", - "react": "~18.1.0", - "react-dom": "~18.1.0", "react-test-renderer": "~18.1.0", - "source-map-explorer": "~2.5.2", "tsbb": "~3.7.0" }, - "dependencies": { - "@babel/runtime": "^7.14.6", - "@uiw/react-markdown-preview": "^4.0.10", - "rehype-sanitize": "~5.0.1", - "rehype": "~12.0.1" + "lint-staged": { + "*.{js,jsx,less,md,json}": [ + "prettier --write" + ], + "*.ts?(x)": [ + "prettier --parser=typescript --write" + ] + }, + "workspaces": [ + "core", + "www" + ], + "engines": { + "node": ">=16.0.0" }, "keywords": [ "react", @@ -84,36 +58,5 @@ "uiw", "uiwjs", "code" - ], - "jest": { - "transformIgnorePatterns": [ - "/node_modules/?!(.*)" - ] - }, - "lint-staged": { - "*.{js,jsx,less,md,json}": [ - "prettier --write" - ], - "*.ts?(x)": [ - "prettier --parser=typescript --write" - ] - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } + ] } diff --git a/tsconfig.json b/tsconfig.json index ec93f1e52..9e035eb6e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,6 +18,5 @@ "noFallthroughCasesInSwitch": true, "noEmit": true, "types": ["jest", "node"] - }, - "include": ["website", "src", ".kktrc.ts", "test"] + } } diff --git a/website/ExampleCustomToolbar.tsx b/website/ExampleCustomToolbar.tsx deleted file mode 100644 index d8ea35dfc..000000000 --- a/website/ExampleCustomToolbar.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React, { useState } from 'react'; -import MDEditor, { commands, ICommand } from '../'; - -const ExampleCustomToolbar = () => { - const title: ICommand = { - name: 'title3', - keyCommand: 'title3', - buttonProps: null, - icon: Custom Toolbar, - }; - const [value, setValue] = useState('Hello Markdown! `Tab` key uses default behavior'); - - return ( - setValue(newValue)} - textareaProps={{ - placeholder: 'Please enter Markdown text', - }} - extraCommands={[ - commands.group([commands.title1, commands.title2], { - name: 'title2', - groupName: 'title2', - buttonProps: { 'aria-label': 'Insert title' }, - }), - commands.group([commands.title3, commands.title4], { - name: 'title3', - groupName: 'title3', - buttonProps: { 'aria-label': 'Insert title' }, - }), - commands.group([commands.title5, commands.title6], { - name: 'title4', - groupName: 'title4', - buttonProps: { 'aria-label': 'Insert title' }, - }), - ]} - commands={[ - title, - commands.group( - [commands.title1, commands.title2, commands.title3, commands.title4, commands.title5, commands.title6], - { - name: 'title', - groupName: 'title', - buttonProps: { 'aria-label': 'Insert title' }, - }, - ), - // commands.bold, commands.hr, commands.italic, commands.divider, - commands.group([], { - name: 'update', - groupName: 'update', - icon: ( - - - - ), - children: (handle) => { - return ( -
-
My Custom Toolbar
- - - -
- ); - }, - execute: (state: commands.TextState, api: commands.TextAreaTextApi) => { - console.log('> execute: >>>>>', state); - }, - buttonProps: { 'aria-label': 'Insert title' }, - }), - // commands.divider, - // commands.codeEdit, commands.codeLive, commands.codePreview, commands.divider, - // commands.fullscreen, - ]} - /> - ); -}; -export default ExampleCustomToolbar; diff --git a/website/ExampleKaTeX.tsx b/website/ExampleKaTeX.tsx deleted file mode 100644 index 45840e6f3..000000000 --- a/website/ExampleKaTeX.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { useState } from 'react'; -import 'katex/dist/katex.css'; -import katex from 'katex'; -import { getCodeString } from 'rehype-rewrite'; -import MDEditor from '../'; - -const mdKaTeX = `This is to display the -\`$$c = \\pm\\sqrt{a^2 + b^2}$$\` - in one line - -\`\`\`KaTeX -c = \\pm\\sqrt{a^2 + b^2} -\`\`\` - -\`\`\`KaTeX -\\\\f\\relax{x} = \\int_{-\\infty}^\\infty - \\\\f\\hat\\xi\\,e^{2 \\pi i \\xi x} - \\,d\\xi -\`\`\` -`; - -const ExampleKaTeX = () => { - const [value, setValue] = useState(mdKaTeX); - return ( - setValue(newValue!)} - textareaProps={{ - placeholder: 'Please enter Markdown text', - }} - previewOptions={{ - components: { - code: ({ inline, children = [], className, ...props }) => { - const txt = children[0] || ''; - if (inline) { - if (typeof txt === 'string' && /^\$\$(.*)\$\$/.test(txt)) { - const html = katex.renderToString(txt.replace(/^\$\$(.*)\$\$/, '$1'), { - throwOnError: false, - }); - return ; - } - return {txt}; - } - const code = props.node && props.node.children ? getCodeString(props.node.children) : txt; - if ( - typeof code === 'string' && - typeof className === 'string' && - /^language-katex/.test(className.toLocaleLowerCase()) - ) { - const html = katex.renderToString(code, { - throwOnError: false, - }); - return ; - } - return {txt}; - }, - }, - }} - /> - ); -}; - -export default ExampleKaTeX; diff --git a/website/ExampleMermaid.tsx b/website/ExampleMermaid.tsx deleted file mode 100644 index ce33e4b73..000000000 --- a/website/ExampleMermaid.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import React, { useState, useRef, useEffect } from 'react'; -// @ts-ignore -import mermaid from 'mermaid'; -import MDEditor from '../'; - -const mdMermaid = `The following are some examples of the diagrams, charts and graphs that can be made using Mermaid and the Markdown-inspired text specific to it. - -\`\`\`mermaid -graph TD -A[Hard] -->|Text| B(Round) -B --> C{Decision} -C -->|One| D[Result 1] -C -->|Two| E[Result 2] -\`\`\` - -\`\`\`mermaid -sequenceDiagram -Alice->>John: Hello John, how are you? -loop Healthcheck - John->>John: Fight against hypochondria -end -Note right of John: Rational thoughts! -John-->>Alice: Great! -John->>Bob: How about you? -Bob-->>John: Jolly good! -\`\`\` -`; - -const randomid = () => parseInt(String(Math.random() * 1e15), 10).toString(36); - -const Code = ({ inline, children = [], className, ...props }: any) => { - const demoid = useRef(`dome${randomid()}`); - const code = getCode(children); - const demo = useRef(null); - useEffect(() => { - if (demo.current) { - try { - const str = mermaid.render(demoid.current, code, () => null, demo.current); - // @ts-ignore - demo.current.innerHTML = str; - } catch (error) { - // @ts-ignore - demo.current.innerHTML = error; - } - } - }, [code, demo]); - - if ( - typeof code === 'string' && - typeof className === 'string' && - /^language-mermaid/.test(className.toLocaleLowerCase()) - ) { - return ( - - - - ); - } - return {children}; -}; - -const getCode = (arr: any = []) => - arr - .map((dt: any) => { - if (typeof dt === 'string') { - return dt; - } - if (dt.props && dt.props.children) { - return getCode(dt.props.children); - } - return false; - }) - .filter(Boolean) - .join(''); - -export default function ExampleMermaid() { - const [value, setValue] = useState(mdMermaid); - return ( - setValue(newValue)} - previewOptions={{ - components: { - code: Code, - }, - }} - /> - ); -} diff --git a/www/.kktrc.ts b/www/.kktrc.ts new file mode 100644 index 000000000..9104e6a26 --- /dev/null +++ b/www/.kktrc.ts @@ -0,0 +1,84 @@ +import path from 'path'; +import webpack, { Configuration } from 'webpack'; +import { LoaderConfOptions } from 'kkt'; +import lessModules from '@kkt/less-modules'; +import scopePluginOptions from '@kkt/scope-plugin-options'; +import { mdCodeModulesLoader } from 'markdown-react-code-preview-loader'; +import pkg from './package.json'; + +export default (conf: Configuration, env: 'production' | 'development', options: LoaderConfOptions) => { + conf = lessModules(conf, env, options); + conf = mdCodeModulesLoader(conf); + conf = scopePluginOptions(conf, env, { + ...options, + allowedFiles: [path.resolve(process.cwd(), 'README.md')], + }); + // Get the project version. + conf.plugins!.push( + new webpack.DefinePlugin({ + VERSION: JSON.stringify(pkg.version), + }), + ); + conf.module!.exprContextCritical = false; + if (env === 'production') { + conf.optimization = { + ...conf.optimization, + splitChunks: { + cacheGroups: { + reactvendor: { + test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/, + name: 'react-vendor', + chunks: 'all', + }, + katex: { + test: /[\\/]node_modules[\\/](katex)[\\/]/, + name: 'katex-vendor', + chunks: 'all', + }, + mermaid: { + test: /[\\/]node_modules[\\/](mermaid)[\\/]/, + name: 'mermaid-vendor', + chunks: 'all', + }, + dagred3: { + test: /[\\/]node_modules[\\/](dagre-d3)[\\/]/, + name: 'dagre-d3-vendor', + chunks: 'all', + }, + momentlodash: { + test: /[\\/]node_modules[\\/](moment-mini|lodash|d3-array|d3-geo|d3-shape|dagre)[\\/]/, + name: 'momentlodash-vendor', + chunks: 'all', + }, + d3: { + test: /[\\/]node_modules[\\/](d3-\w+(-?\w+))[\\/]/, + name: 'd3-vendor', + chunks: 'all', + }, + micromark: { + test: /[\\/]node_modules[\\/](micromark)[\\/]/, + name: 'micromark-vendor', + chunks: 'all', + }, + prismjs: { + test: /[\\/]node_modules[\\/](refractor)[\\/]/, + name: 'refractor-prismjs-vendor', + chunks: 'all', + }, + runtime: { + test: /[\\/]node_modules[\\/](@babel[\\/]runtime)[\\/]/, + name: 'babel-runtime-vendor', + chunks: 'all', + }, + parse5: { + test: /[\\/]node_modules[\\/](parse5)[\\/]/, + name: 'parse5-vendor', + chunks: 'all', + }, + }, + }, + }; + conf.output = { ...conf.output, publicPath: './' }; + } + return conf; +}; diff --git a/www/package.json b/www/package.json new file mode 100644 index 000000000..5f8a5f2d9 --- /dev/null +++ b/www/package.json @@ -0,0 +1,58 @@ +{ + "name": "www", + "private": true, + "version": "3.14.1", + "description": "A markdown editor with preview, implemented with React.js and TypeScript.", + "homepage": "https://uiwjs.github.io/react-md-editor/", + "author": "kenny wang ", + "main": "lib/index.js", + "module": "esm/index.js", + "scripts": { + "build": "kkt build", + "start": "kkt start", + "map": "source-map-explorer build/static/js/*.js --html build/website-result.html" + }, + "license": "MIT", + "devDependencies": { + "@kkt/less-modules": "~7.1.1", + "@kkt/raw-modules": "~7.1.1", + "@kkt/scope-plugin-options": "~7.1.1", + "@types/katex": "~0.14.0", + "@types/react": "~18.0.9", + "@types/react-dom": "~18.0.3", + "kkt": "~7.1.5", + "markdown-react-code-preview-loader": "^2.1.2", + "source-map-explorer": "~2.5.2" + }, + "dependencies": { + "@uiw/react-github-corners": "~1.5.3", + "@uiw/react-md-editor": "3.14.1", + "@uiw/react-shields": "~1.1.2", + "@wcj/dark-mode": "~1.0.9", + "dom-to-image": "^2.6.0", + "katex": "~0.15.2", + "mermaid": "~8.14.0", + "react": "~18.1.0", + "react-code-preview-layout": "^2.0.4", + "react-dom": "~18.1.0", + "rehype-sanitize": "~5.0.1" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/public/bundle.html b/www/public/bundle.html similarity index 100% rename from public/bundle.html rename to www/public/bundle.html diff --git a/public/favicon.ico b/www/public/favicon.ico similarity index 100% rename from public/favicon.ico rename to www/public/favicon.ico diff --git a/public/index.html b/www/public/index.html similarity index 100% rename from public/index.html rename to www/public/index.html diff --git a/website/App.less b/www/src/App.less similarity index 100% rename from website/App.less rename to www/src/App.less diff --git a/website/App.tsx b/www/src/App.tsx similarity index 70% rename from website/App.tsx rename to www/src/App.tsx index 212e43cf8..76b53b9a4 100644 --- a/website/App.tsx +++ b/www/src/App.tsx @@ -1,17 +1,12 @@ import React from 'react'; import GithubCorner from '@uiw/react-github-corners'; import '@wcj/dark-mode'; -import MDEditor from '../'; -import ReadmeStr from '../README.md'; +import ReadmeStr from '@uiw/react-md-editor/README.md'; import Example from './Example'; -import ExampleKaTeX from './ExampleKaTeX'; -import ExampleMermaid from './ExampleMermaid'; -import ExampleCustomToolbar from './ExampleCustomToolbar'; import { ReactComponent as Banner } from './banner.svg'; import './App.less'; import pkg from '../package.json'; - -const mdStr = ReadmeStr.replace(/([\s\S]*)/, '').replace(/^\s+/, ''); +import Markdown from './Markdown'; export default function App() { const openVersionWebsite = (e: React.ChangeEvent) => { @@ -77,38 +72,8 @@ export default function App() { Open in unpkg
- -
- Custom toolbar. - - Example Code - -
- -
- Support Custom KaTeX Preview. - - Example Code - -
- -
- Support Custom Mermaid Preview. - - Example Code - -
- - /, '')} /> + +
); diff --git a/website/Example.tsx b/www/src/Example.tsx similarity index 98% rename from website/Example.tsx rename to www/src/Example.tsx index c8c701256..5d5e54fb0 100644 --- a/website/Example.tsx +++ b/www/src/Example.tsx @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import rehypeSanitize, { defaultSchema } from 'rehype-sanitize'; -import MDEditor, { MDEditorProps } from '../'; +import MDEditor, { MDEditorProps } from '@uiw/react-md-editor'; let count = 1; diff --git a/www/src/Markdown.tsx b/www/src/Markdown.tsx new file mode 100644 index 000000000..9a3bf8359 --- /dev/null +++ b/www/src/Markdown.tsx @@ -0,0 +1,50 @@ +import { useEffect, useRef } from 'react'; +import CodeLayout from 'react-code-preview-layout'; +import { getMetaId, isMeta, getURLParameters } from 'markdown-react-code-preview-loader'; +import MDEditor from '@uiw/react-md-editor'; +import data from '@uiw/react-md-editor/README.md'; +import { CodeComponent, ReactMarkdownNames } from 'react-markdown/lib/ast-to-react'; + +const CodePreview: CodeComponent | ReactMarkdownNames = ({ inline, node, ...props }) => { + const $dom = useRef(null); + const { 'data-meta': meta, ...rest } = props as any; + + useEffect(() => { + if ($dom.current) { + const parentElement = $dom.current.parentElement; + if (parentElement && parentElement.parentElement) { + parentElement.parentElement.replaceChild($dom.current, parentElement); + } + } + }, [$dom]); + + if (inline || !isMeta(meta)) { + return ; + } + const line = node.position?.start.line; + const metaId = getMetaId(meta) || String(line); + const Child = data.components[`${metaId}`]; + if (metaId && typeof Child === 'function') { + const code = data.data[metaId].value || ''; + const param = getURLParameters(meta); + return ( + } text={code}> + + + ); + } + return ; +}; + +export default function Markdown() { + return ( + + ); +} diff --git a/website/banner.svg b/www/src/banner.svg similarity index 100% rename from website/banner.svg rename to www/src/banner.svg diff --git a/website/index.tsx b/www/src/index.tsx similarity index 100% rename from website/index.tsx rename to www/src/index.tsx index e51b681ff..824a02fcf 100644 --- a/website/index.tsx +++ b/www/src/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import App from './App'; import { createRoot } from 'react-dom/client'; +import App from './App'; const container = document.getElementById('root'); const root = createRoot(container!); diff --git a/website/react-app-env.d.ts b/www/src/react-app-env.d.ts similarity index 59% rename from website/react-app-env.d.ts rename to www/src/react-app-env.d.ts index 8642661ed..087bce7ca 100644 --- a/website/react-app-env.d.ts +++ b/www/src/react-app-env.d.ts @@ -6,6 +6,7 @@ declare module '*.less' { } declare module '*.md' { - const file: string; - export default file; + import { CodeBlockData } from 'markdown-react-code-preview-loader'; + const src: CodeBlockData; + export default src; } diff --git a/src/tsconfig.json b/www/tsconfig.json similarity index 71% rename from src/tsconfig.json rename to www/tsconfig.json index 0379fc8fa..b03720394 100644 --- a/src/tsconfig.json +++ b/www/tsconfig.json @@ -1,7 +1,8 @@ { "extends": "../tsconfig", + "include": ["./src"], "compilerOptions": { - "baseUrl": "../cjs", + "baseUrl": ".", "emitDeclarationOnly": true, "noEmit": false }