├── .npmrc
├── img
└── screenshot.png
├── src
├── index.js
├── sass
│ ├── variables.scss
│ ├── icon.scss
│ ├── menubar.scss
│ ├── menububble.scss
│ ├── main.scss
│ └── editor.scss
├── assets
│ └── icons
│ │ ├── hr.svg
│ │ ├── italic.svg
│ │ ├── ul.svg
│ │ ├── redo.svg
│ │ ├── paragraph.svg
│ │ ├── undo.svg
│ │ ├── underline.svg
│ │ ├── code.svg
│ │ ├── bold.svg
│ │ ├── quote.svg
│ │ ├── remove.svg
│ │ ├── mention.svg
│ │ ├── image.svg
│ │ ├── checklist.svg
│ │ ├── strike.svg
│ │ ├── ol.svg
│ │ ├── link.svg
│ │ ├── combine_cells.svg
│ │ ├── delete_col.svg
│ │ ├── delete_row.svg
│ │ ├── table.svg
│ │ ├── github.svg
│ │ ├── add_row_after.svg
│ │ ├── add_col_after.svg
│ │ ├── add_row_before.svg
│ │ ├── add_col_before.svg
│ │ └── delete_table.svg
└── components
│ ├── InlineSvg.vue
│ ├── Icon.vue
│ └── Editor.vue
├── example
├── main.js
└── App.vue
├── .github
└── dependabot.yml
├── .npmignore
├── .gitignore
├── index.html
├── .prettierrc.json
├── LICENSE.md
├── vite.config.js
├── README.md
├── package.json
└── eslint.config.js
/.npmrc:
--------------------------------------------------------------------------------
1 | tag-version-prefix=""
--------------------------------------------------------------------------------
/img/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/neverbot/vue-tiptap/HEAD/img/screenshot.png
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import Editor from './components/Editor.vue';
2 |
3 | export default Editor;
4 |
--------------------------------------------------------------------------------
/src/sass/variables.scss:
--------------------------------------------------------------------------------
1 | $color-black: #000000;
2 | $color-white: #ffffff;
3 | $color-grey: #dddddd;
4 |
--------------------------------------------------------------------------------
/example/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue';
2 | import App from './App.vue';
3 |
4 | createApp(App).mount('#app');
5 |
--------------------------------------------------------------------------------
/src/sass/icon.scss:
--------------------------------------------------------------------------------
1 | .icon {
2 | position: relative;
3 | width: 100%;
4 | height: 100%;
5 |
6 | &.has-align-fix {
7 | top: -.1rem;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Basic dependabot set up
2 |
3 | version: 2
4 | updates:
5 |
6 | # Maintain dependencies for npm
7 | - package-ecosystem: "npm"
8 | directory: "/"
9 | schedule:
10 | interval: "monthly"
11 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist/
3 |
4 | # log files
5 | npm-debug.log*
6 | yarn-debug.log*
7 | yarn-error.log*
8 |
9 | # editor directories and files
10 | .idea
11 | .vscode
12 | *.suo
13 | *.ntvs*
14 | *.njsproj
15 | *.sln
16 | *.sw*
17 |
--------------------------------------------------------------------------------
/src/assets/icons/hr.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | # dist/
4 | !dist/.gitkeep
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # editor directories and files
16 | .idea
17 | .vscode
18 | *.suo
19 | *.ntvs*
20 | *.njsproj
21 | *.sln
22 | *.sw*
23 |
--------------------------------------------------------------------------------
/src/assets/icons/italic.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/ul.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite + Vue
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/assets/icons/redo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/paragraph.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "useTabs": false,
3 | "printWidth": 79,
4 | "tabWidth": 2,
5 | "singleQuote": true,
6 | "semi": true,
7 | "arrowParens": "always",
8 | "bracketSpacing": true,
9 | "overrides": [
10 | {
11 | "files": "*.vue",
12 | "options": {
13 | "htmlWhitespaceSensitivity": "css"
14 | }
15 | },
16 | {
17 | "files": "*.json",
18 | "options": {
19 | "parser": "json"
20 | }
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/src/assets/icons/undo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/underline.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/code.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/bold.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/quote.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/remove.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/mention.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/InlineSvg.vue:
--------------------------------------------------------------------------------
1 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/assets/icons/image.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/checklist.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/Icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/assets/icons/strike.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/ol.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/link.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/assets/icons/combine_cells.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/sass/menubar.scss:
--------------------------------------------------------------------------------
1 | .menubar {
2 |
3 | margin-bottom: 1rem;
4 | transition: visibility 0.2s 0.4s, opacity 0.2s 0.4s;
5 |
6 | &.is-hidden {
7 | visibility: hidden;
8 | opacity: 0;
9 | }
10 |
11 | &.is-focused {
12 | visibility: visible;
13 | opacity: 1;
14 | transition: visibility 0.2s, opacity 0.2s;
15 | }
16 |
17 | &__button {
18 | vertical-align: middle;
19 | width: 1.8rem;
20 | height: 1.2rem;
21 | font-weight: bold;
22 | display: inline-flex;
23 | background: transparent;
24 | border: 0;
25 | color: $color-black;
26 | padding: 0.2rem 0.5rem;
27 | margin-right: 0.2rem;
28 | border-radius: 3px;
29 | cursor: pointer;
30 |
31 | &:hover {
32 | background-color: rgba($color-black, 0.05);
33 | }
34 |
35 | &.is-active {
36 | background-color: rgba($color-black, 0.1);
37 | }
38 | }
39 |
40 | span#{&}__button {
41 | font-size: 13.3333px;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/assets/icons/delete_col.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/icons/delete_row.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/icons/table.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/icons/github.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019, neverbot (limited liability)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/sass/menububble.scss:
--------------------------------------------------------------------------------
1 | .menububble {
2 | position: absolute;
3 | display: flex;
4 | z-index: 20;
5 | background: $color-black;
6 | border-radius: 5px;
7 | padding: 0.3rem;
8 | margin-bottom: 0.5rem;
9 | transform: translateX(-50%);
10 | visibility: hidden;
11 | opacity: 0;
12 | transition: opacity 0.2s, visibility 0.2s;
13 |
14 | &.is-active {
15 | opacity: 1;
16 | visibility: visible;
17 | }
18 |
19 | &__button {
20 | display: inline-flex;
21 | background: transparent;
22 | border: 0;
23 | color: $color-white;
24 | padding: 0.2rem 0.5rem;
25 | margin-right: 0.2rem;
26 | border-radius: 3px;
27 | cursor: pointer;
28 |
29 | &:last-child {
30 | margin-right: 0;
31 | }
32 |
33 | &:hover {
34 | background-color: rgba($color-white, 0.1);
35 | }
36 |
37 | &.is-active {
38 | background-color: rgba($color-white, 0.2);
39 | }
40 | }
41 |
42 | &__form {
43 | display: flex;
44 | align-items: center;
45 | }
46 |
47 | &__input {
48 | font: inherit;
49 | border: none;
50 | background: transparent;
51 | color: $color-white;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import vue from '@vitejs/plugin-vue';
3 |
4 | import path from 'path';
5 |
6 | export default defineConfig({
7 | plugins: [vue()],
8 | css: {
9 | preprocessorOptions: {
10 | sass: {
11 | // To fix Deprecation [legacy-js-api]: The legacy JS API is deprecated
12 | // More info: https://sass-lang.com/d/legacy-js-api
13 | api: 'modern-compiler', // or 'modern'
14 | },
15 | },
16 | },
17 | resolve: {
18 | alias: {
19 | '@': path.resolve(__dirname, './src'),
20 | },
21 | },
22 | build: {
23 | lib: {
24 | // src/index.js is where we have exported the component(s)
25 | entry: path.resolve(__dirname, 'src/index.js'),
26 | name: 'VueTipTap',
27 | // the name of the output files when the build is run
28 | fileName: 'vue-tiptap',
29 | },
30 | rollupOptions: {
31 | // make sure to externalize deps that shouldn't be bundled
32 | // into your library
33 | external: ['vue'],
34 | output: {
35 | // Provide global variables to use in the UMD build
36 | // for externalized deps
37 | globals: {
38 | vue: 'Vue',
39 | },
40 | },
41 | },
42 | },
43 | });
44 |
--------------------------------------------------------------------------------
/src/assets/icons/add_row_after.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/icons/add_col_after.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/icons/add_row_before.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/icons/add_col_before.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/assets/icons/delete_table.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-tiptap
2 |
3 | [](https://www.npmjs.com/package/vue-tiptap)
4 | [](https://www.npmjs.com/package/vue-tiptap)
5 | [](https://github.com/neverbot/vue-tiptap/blob/master/LICENSE.md)
6 | [](https://www.npmjs.com/package/vue-tiptap)
7 |
8 | Example of using [tiptap 2](https://github.com/scrumpy/tiptap/) as a Vue 3 component without being completely renderless, so you can see how to use it inside your own components or even use it right away. It can be imported as a Vue 3 component, and you can see in the `example` directory how it would be used inside your application.
9 |
10 | **Note**: now tiptap has their own examples and components for different frameworks (including vue 2 and vue 3), so maybe you should take a look to the official package [@tiptap/vue-3](https://tiptap.dev/installation/vue3). This package will not be updated anymore.
11 |
12 | 
13 |
14 | ## Install and Usage
15 |
16 | ```bash
17 |
18 | # install dependencies
19 | npm install
20 |
21 | # build component
22 | npm run build
23 |
24 | # serve demo
25 | npm run dev
26 | ```
27 |
28 | ## License
29 |
30 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
31 |
32 | SVG Icons from the original [TipTap](https://github.com/scrumpy/tiptap/) package.
33 |
--------------------------------------------------------------------------------
/src/sass/main.scss:
--------------------------------------------------------------------------------
1 | @import "./variables";
2 |
3 | * {
4 | margin: 0;
5 | padding: 0;
6 | box-sizing: border-box;
7 | text-size-adjust: 100%;
8 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
9 | -webkit-touch-callout: none;
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | text-rendering: optimizeLegibility;
13 |
14 | &:focus {
15 | outline: none;
16 | }
17 | }
18 |
19 | *::before,
20 | *::after {
21 | box-sizing: border-box;
22 | }
23 |
24 | html {
25 | font-family: 'Inter';
26 | font-size: 18px;
27 | color: $color-black;
28 | line-height: 1.5;
29 | }
30 |
31 | body {
32 | margin: 0;
33 | }
34 |
35 | a {
36 | color: inherit;
37 | }
38 |
39 | h1,
40 | h2,
41 | h3,
42 | p,
43 | ul,
44 | ol,
45 | pre,
46 | blockquote {
47 | margin: 1rem 0;
48 |
49 | &:first-child {
50 | margin-top: 0;
51 | }
52 |
53 | &:last-child {
54 | margin-bottom: 0;
55 | }
56 | }
57 |
58 | h1,
59 | h2,
60 | h3 {
61 | line-height: 1.3;
62 | }
63 |
64 | .button {
65 | font-weight: bold;
66 | display: inline-flex;
67 | background: transparent;
68 | border: 0;
69 | color: $color-black;
70 | padding: 0.2rem 0.5rem;
71 | margin-right: 0.2rem;
72 | border-radius: 3px;
73 | cursor: pointer;
74 | background-color: rgba($color-black, 0.1);
75 |
76 | &:hover {
77 | background-color: rgba($color-black, 0.15);
78 | }
79 | }
80 |
81 | .message {
82 | background-color: rgba($color-black, 0.05);
83 | color: rgba($color-black, 0.7);
84 | padding: 1rem;
85 | border-radius: 6px;
86 | margin-bottom: 1.5rem;
87 | font-style: italic;
88 | }
89 |
90 | @import "./icon";
91 | @import "./editor";
92 | @import "./menubar";
93 | @import "./menububble";
94 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-tiptap",
3 | "version": "3.1.2",
4 | "description": "Vue component to use TipTap Editor without being renderless",
5 | "keywords": [
6 | "vue",
7 | "tiptap",
8 | "vuejs"
9 | ],
10 | "bugs": {
11 | "url": "https://github.com/neverbot/vue-tiptap/issues"
12 | },
13 | "type": "module",
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/neverbot/vue-tiptap"
17 | },
18 | "license": "MIT",
19 | "author": "neverbot (http://neverbot.com)",
20 | "exports": {
21 | ".": {
22 | "import": "./dist/vue-tiptap.js",
23 | "require": "./dist/vue-tiptap.umd.cjs"
24 | }
25 | },
26 | "main": "./dist/vue-tiptap.umd.cjs",
27 | "module": "./dist/vue-tiptap.js",
28 | "scripts": {
29 | "build": "npx vite build",
30 | "dev": "npx vite",
31 | "lint": "npx eslint .",
32 | "lint:fix": "npx eslint --fix .",
33 | "serve": "npx vite preview",
34 | "test": "echo \"Error: no tests\" && exit 1"
35 | },
36 | "dependencies": {
37 | "@tiptap/extension-underline": "^2.8.0",
38 | "@tiptap/starter-kit": "^2.8.0",
39 | "@tiptap/vue-3": "^2.8.0",
40 | "vue": "^3.5.10"
41 | },
42 | "devDependencies": {
43 | "@babel/core": "^7.25.2",
44 | "@babel/eslint-parser": "^7.25.1",
45 | "@babel/preset-env": "^7.25.4",
46 | "@eslint/js": "^9.11.1",
47 | "@vitejs/plugin-vue": "^5.1.4",
48 | "babel-loader": "^9.2.1",
49 | "eslint": "^9.11.1",
50 | "eslint-config-prettier": "^9.1.0",
51 | "eslint-plugin-jsonc": "^2.16.0",
52 | "eslint-plugin-prettier": "^5.2.1",
53 | "eslint-plugin-vue": "^9.28.0",
54 | "globals": "^15.10.0",
55 | "jsonc-eslint-parser": "^2.4.0",
56 | "prettier": "^3.3.3",
57 | "sass": "^1.79.4",
58 | "vite": "^5.4.8",
59 | "vue-eslint-parser": "^9.4.3"
60 | },
61 | "engines": {
62 | "node": "^14 || ^16 || ^18 || ^20",
63 | "npm": "^7 || ^8 || ^9 || ^10"
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/example/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
vue-tiptap example
4 |
45 |
46 |
47 |
48 |
67 |
68 |
71 |
72 |
87 |
--------------------------------------------------------------------------------
/src/sass/editor.scss:
--------------------------------------------------------------------------------
1 | .editor {
2 | position: relative;
3 | max-width: 30rem;
4 | margin: 0 auto 5rem auto;
5 |
6 | &__content {
7 |
8 | overflow-wrap: break-word;
9 | word-wrap: break-word;
10 | word-break: break-word;
11 |
12 | * {
13 | caret-color: currentColor;
14 | }
15 |
16 | pre {
17 | padding: 0.7rem 1rem;
18 | border-radius: 5px;
19 | background: $color-black;
20 | color: $color-white;
21 | font-size: 0.8rem;
22 | overflow-x: auto;
23 |
24 | code {
25 | display: block;
26 | }
27 | }
28 |
29 | p code {
30 | padding: 0.2rem 0.4rem;
31 | border-radius: 5px;
32 | font-size: 0.8rem;
33 | font-weight: bold;
34 | background: rgba($color-black, 0.1);
35 | color: rgba($color-black, 0.8);
36 | }
37 |
38 | ul,
39 | ol {
40 | padding-left: 1rem;
41 | }
42 |
43 | li > p,
44 | li > ol,
45 | li > ul {
46 | margin: 0;
47 | }
48 |
49 | a {
50 | color: inherit;
51 | }
52 |
53 | blockquote {
54 | border-left: 3px solid rgba($color-black, 0.1);
55 | color: rgba($color-black, 0.8);
56 | padding-left: 0.8rem;
57 | font-style: italic;
58 |
59 | p {
60 | margin: 0;
61 | }
62 | }
63 |
64 | img {
65 | max-width: 100%;
66 | border-radius: 3px;
67 | }
68 |
69 | table {
70 | border-collapse: collapse;
71 | table-layout: fixed;
72 | width: 100%;
73 | margin: 0;
74 | overflow: hidden;
75 |
76 | td, th {
77 | min-width: 1em;
78 | border: 2px solid $color-grey;
79 | padding: 3px 5px;
80 | vertical-align: top;
81 | box-sizing: border-box;
82 | position: relative;
83 | > * {
84 | margin-bottom: 0;
85 | }
86 | }
87 |
88 | th {
89 | font-weight: bold;
90 | text-align: left;
91 | }
92 |
93 | .selectedCell:after {
94 | z-index: 2;
95 | position: absolute;
96 | content: "";
97 | left: 0; right: 0; top: 0; bottom: 0;
98 | background: rgba(200, 200, 255, 0.4);
99 | pointer-events: none;
100 | }
101 |
102 | .column-resize-handle {
103 | position: absolute;
104 | right: -2px; top: 0; bottom: 0;
105 | width: 4px;
106 | z-index: 20;
107 | background-color: #adf;
108 | pointer-events: none;
109 | }
110 | }
111 |
112 | .tableWrapper {
113 | margin: 1em 0;
114 | overflow-x: auto;
115 | }
116 |
117 | .resize-cursor {
118 | cursor: ew-resize;
119 | cursor: col-resize;
120 | }
121 |
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import globals from 'globals';
2 | import babelParser from '@babel/eslint-parser';
3 | import eslintJsonc from 'eslint-plugin-jsonc';
4 | import eslintJsoncParser from 'jsonc-eslint-parser';
5 | import vueParser from 'vue-eslint-parser';
6 | import vue from 'eslint-plugin-vue';
7 | import prettier from 'eslint-plugin-prettier';
8 | import js from '@eslint/js';
9 |
10 | export default [
11 | {
12 | // global ignores
13 | // folders can only be ignored at the global level, per-cfg you must do: '**/dist/**/*'
14 | ignores: ['**/dist/'],
15 | },
16 | // general defaults
17 | js.configs.recommended,
18 | {
19 | files: ['**/*.js'],
20 | rules: {
21 | 'prettier/prettier': [
22 | 'error',
23 | {},
24 | {
25 | usePrettierrc: true,
26 | },
27 | ],
28 | 'no-console': 'warn',
29 | },
30 | plugins: {
31 | prettier,
32 | },
33 | languageOptions: {
34 | parser: babelParser,
35 | ecmaVersion: 2018,
36 | sourceType: 'module',
37 | globals: {
38 | ...globals.node,
39 | ...globals.browser,
40 | },
41 | parserOptions: {
42 | requireConfigFile: false,
43 | allowImportExportEverywhere: true,
44 |
45 | ecmaFeatures: {
46 | experimentalObjectRestSpread: true,
47 | },
48 | },
49 | },
50 | },
51 | {
52 | files: ['**/*.json'],
53 | ignores: ['**/package.json', '**/package-lock.json'],
54 | plugins: {
55 | jsonc: eslintJsonc,
56 | prettier,
57 | },
58 | languageOptions: {
59 | parser: eslintJsoncParser,
60 | parserOptions: {
61 | jsonSyntax: 'JSON',
62 | },
63 | },
64 | rules: {
65 | 'prettier/prettier': [
66 | 'error',
67 | {},
68 | {
69 | usePrettierrc: true,
70 | },
71 | ],
72 | 'no-console': 'warn',
73 | },
74 | },
75 | ...vue.configs['flat/essential'],
76 | ...vue.configs['flat/recommended'],
77 | {
78 | files: ['**/*.vue'],
79 | plugins: {
80 | prettier,
81 | vue,
82 | },
83 | languageOptions: {
84 | parser: vueParser,
85 | ecmaVersion: 'latest',
86 | sourceType: 'module',
87 | globals: {
88 | ...globals.node,
89 | ...globals.browser,
90 | },
91 | },
92 | processor: vue.processors['.vue'],
93 | rules: {
94 | 'prettier/prettier': [
95 | 'error',
96 | {},
97 | {
98 | usePrettierrc: true,
99 | },
100 | ],
101 | ...vue.configs.base.rules,
102 | ...vue.configs.recommended.rules,
103 | ...vue.configs.essential.rules,
104 | ...vue.configs['strongly-recommended'].rules,
105 | 'no-console': 'warn',
106 | 'vue/multi-word-component-names': 'off',
107 | 'vue/no-v-html': 'off',
108 | 'vue/first-attribute-linebreak': [
109 | 'warn',
110 | {
111 | singleline: 'ignore',
112 | multiline: 'below',
113 | },
114 | ],
115 | 'vue/max-attributes-per-line': [
116 | 'error',
117 | {
118 | singleline: {
119 | max: 3,
120 | },
121 | multiline: {
122 | max: 1,
123 | },
124 | },
125 | ],
126 | 'vue/html-indent': [
127 | 'error',
128 | 2,
129 | {
130 | attribute: 1,
131 | baseIndent: 1,
132 | closeBracket: 0,
133 | alignAttributesVertically: false,
134 | ignores: [],
135 | },
136 | ],
137 | },
138 | },
139 | ];
140 |
--------------------------------------------------------------------------------
/src/components/Editor.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
137 |
138 |
139 |
140 |
141 |
142 |
220 |
221 |
222 |
--------------------------------------------------------------------------------