├── .gitignore ├── LICENSE ├── README.md ├── examples ├── Basic.vue ├── CustomFormat.vue ├── EventListening.vue └── Html.vue ├── package.json ├── src ├── Quill.vue └── formats │ ├── GrammarlyInline.js │ └── Shortcode.js ├── vue-quill.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Croud Support 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-quill 2 | [![npm version](https://badge.fury.io/js/vue-quill.svg)](https://badge.fury.io/js/vue-quill) 3 | 4 | A vue component wrapping the quill editor 5 | 6 | ## Demo 7 | You can view a basic demo of this component in this [CodeSandbox](https://codesandbox.io/s/nnw7rwx48m) 8 | 9 | ## Installation 10 | ``` 11 | npm install --save vue-quill 12 | -or- 13 | yarn add vue-quill 14 | ``` 15 | 16 | You will also need to include the following css file in your project 17 | ```html 18 | 19 | ``` 20 | 21 | ## Vue 1 22 | For Vue 1 components use v0.1.5 or earlier 23 | 24 | ## Usage 25 | Install the vue plugin 26 | ```js 27 | import Vue from 'vue' 28 | import VueQuill from 'vue-quill' 29 | 30 | Vue.use(VueQuill) 31 | ``` 32 | ### Component 33 | ```html 34 | 35 | ``` 36 | You may want to initialize the synced variable as a valid delta object too 37 | 38 | ```js 39 | data() { 40 | return { 41 | content: { 42 | ops: [], 43 | }, 44 | } 45 | } 46 | ``` 47 | 48 | ### Configuration 49 | ```html 50 | 51 | ``` 52 | You can also provide a config object as described in http://quilljs.com/docs/configuration/ 53 | 54 | ```js 55 | data() { 56 | return { 57 | content: { 58 | ops: [], 59 | }, 60 | config: { 61 | readOnly: true, 62 | placeholder: 'Compose an epic...', 63 | }, 64 | } 65 | } 66 | ``` 67 | 68 | ## Options 69 | By default, the component outputs the content as a delta object, you can pass in a prop to return raw html 70 | ```html 71 | 72 | ``` 73 | 74 | ## Custom Formats 75 | To add custom formats to the editor, you can pass an array of formats as a prop. The array should be in the following format 76 | ```js 77 | formats: [ 78 | { 79 | name: 'custom', 80 | options: { 81 | attribute: 'custom', 82 | }, 83 | }, 84 | ], 85 | ``` 86 | 87 | ## Custom Keybindings 88 | You can add custom keybindings by passing through an array in the props, the array should be in the following format 89 | ```js 90 | keyBindings: [ 91 | { 92 | key: 's', 93 | method: function(range) { 94 | this.$dispatch('save', this.editor, range) 95 | return false 96 | }, 97 | }, 98 | ] 99 | ``` 100 | 101 | ## Events 102 | This quill component emits events when the text or selection changes on the quill editor 103 | ```html 104 | 105 | 106 | 19 | -------------------------------------------------------------------------------- /examples/CustomFormat.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 30 | 31 | 50 | -------------------------------------------------------------------------------- /examples/EventListening.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 50 | -------------------------------------------------------------------------------- /examples/Html.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-quill", 3 | "version": "1.5.0", 4 | "description": "Vue quill component and filter", 5 | "main": "vue-quill.js", 6 | "browserify": { 7 | "transform": [ 8 | "babelify", 9 | "vueify" 10 | ] 11 | }, 12 | "scripts": { 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/CroudSupport/vue-quill.git" 18 | }, 19 | "keywords": [ 20 | "vue", 21 | "quill", 22 | "js", 23 | "plugin", 24 | "text", 25 | "editor" 26 | ], 27 | "author": "Brock Reece", 28 | "license": "ISC", 29 | "bugs": { 30 | "url": "https://github.com/CroudSupport/vue-quill/issues" 31 | }, 32 | "homepage": "https://github.com/CroudSupport/vue-quill#readme", 33 | "dependencies": { 34 | "lodash.defaultsdeep": "^4.6.0", 35 | "quill": "^1.3.0", 36 | "quill-render": "^1.0.5" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Quill.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 165 | -------------------------------------------------------------------------------- /src/formats/GrammarlyInline.js: -------------------------------------------------------------------------------- 1 | import Quill from 'quill' 2 | 3 | const Inline = Quill.import('blots/inline') 4 | 5 | class GrammarlyInline extends Inline {} 6 | GrammarlyInline.tagName = 'G' 7 | GrammarlyInline.blotName = 'grammarly-inline' 8 | GrammarlyInline.className = 'gr_' 9 | 10 | export default GrammarlyInline 11 | -------------------------------------------------------------------------------- /src/formats/Shortcode.js: -------------------------------------------------------------------------------- 1 | import Quill from 'quill'; 2 | 3 | const InlineEmbed = Quill.import('blots/embed'); 4 | 5 | class Shortcode extends InlineEmbed { 6 | static create(value) { 7 | const node = super.create(value); 8 | node.setAttribute('class', 'ql-shortcode'); 9 | node.innerHTML = value; 10 | 11 | return node; 12 | } 13 | } 14 | Shortcode.blotName = 'shortcode'; 15 | Shortcode.tagName = 'span'; 16 | 17 | 18 | export default Shortcode; 19 | -------------------------------------------------------------------------------- /vue-quill.js: -------------------------------------------------------------------------------- 1 | import render from 'quill-render' 2 | import Quill from './src/Quill.vue' 3 | 4 | export default { 5 | install: function (Vue, options) { 6 | Vue.component('quill', Quill); 7 | 8 | render.format.inline.underline = function($) { 9 | return $(''); 10 | }; 11 | 12 | Vue.filter('quill', function(value) { 13 | return render(value.ops); 14 | }); 15 | 16 | Vue.filter('quill-preview', function(value, limit) { 17 | const text = value.ops.map(function(op) { 18 | return op.insert 19 | }).join(' ') 20 | 21 | if (typeof limit !== 'undefined' && text.length > limit) { 22 | return text.substring(0, parseInt(limit, 10)) + '...' 23 | } 24 | 25 | return text 26 | }); 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | boolbase@~1.0.0: 6 | version "1.0.0" 7 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" 8 | 9 | cheerio@^0.19.0: 10 | version "0.19.0" 11 | resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.19.0.tgz#772e7015f2ee29965096d71ea4175b75ab354925" 12 | dependencies: 13 | css-select "~1.0.0" 14 | dom-serializer "~0.1.0" 15 | entities "~1.1.1" 16 | htmlparser2 "~3.8.1" 17 | lodash "^3.2.0" 18 | 19 | clone@~2.1.1: 20 | version "2.1.1" 21 | resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" 22 | 23 | core-util-is@~1.0.0: 24 | version "1.0.2" 25 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 26 | 27 | css-select@~1.0.0: 28 | version "1.0.0" 29 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.0.0.tgz#b1121ca51848dd264e2244d058cee254deeb44b0" 30 | dependencies: 31 | boolbase "~1.0.0" 32 | css-what "1.0" 33 | domutils "1.4" 34 | nth-check "~1.0.0" 35 | 36 | css-what@1.0: 37 | version "1.0.0" 38 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-1.0.0.tgz#d7cc2df45180666f99d2b14462639469e00f736c" 39 | 40 | deep-equal@^1.0.1, deep-equal@~1.0.1: 41 | version "1.0.1" 42 | resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" 43 | 44 | dom-serializer@0, dom-serializer@~0.1.0: 45 | version "0.1.0" 46 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" 47 | dependencies: 48 | domelementtype "~1.1.1" 49 | entities "~1.1.1" 50 | 51 | domelementtype@1: 52 | version "1.3.0" 53 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" 54 | 55 | domelementtype@~1.1.1: 56 | version "1.1.3" 57 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" 58 | 59 | domhandler@2.3: 60 | version "2.3.0" 61 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" 62 | dependencies: 63 | domelementtype "1" 64 | 65 | domutils@1.4: 66 | version "1.4.3" 67 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.4.3.tgz#0865513796c6b306031850e175516baf80b72a6f" 68 | dependencies: 69 | domelementtype "1" 70 | 71 | domutils@1.5: 72 | version "1.5.1" 73 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" 74 | dependencies: 75 | dom-serializer "0" 76 | domelementtype "1" 77 | 78 | entities@1.0: 79 | version "1.0.0" 80 | resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" 81 | 82 | entities@~1.1.1: 83 | version "1.1.1" 84 | resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" 85 | 86 | escape-html@^1.0.3: 87 | version "1.0.3" 88 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 89 | 90 | eventemitter3@~2.0.3: 91 | version "2.0.3" 92 | resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba" 93 | 94 | extend@^3.0.0, extend@~3.0.1: 95 | version "3.0.1" 96 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" 97 | 98 | fast-diff@1.1.1: 99 | version "1.1.1" 100 | resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.1.tgz#0aea0e4e605b6a2189f0e936d4b7fbaf1b7cfd9b" 101 | 102 | htmlparser2@~3.8.1: 103 | version "3.8.3" 104 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" 105 | dependencies: 106 | domelementtype "1" 107 | domhandler "2.3" 108 | domutils "1.5" 109 | entities "1.0" 110 | readable-stream "1.1" 111 | 112 | inherits@~2.0.1: 113 | version "2.0.3" 114 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 115 | 116 | isarray@0.0.1: 117 | version "0.0.1" 118 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 119 | 120 | lodash.defaultsdeep@^4.6.0: 121 | version "4.6.0" 122 | resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz#bec1024f85b1bd96cbea405b23c14ad6443a6f81" 123 | 124 | lodash@^3.2.0: 125 | version "3.10.1" 126 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" 127 | 128 | nth-check@~1.0.0: 129 | version "1.0.1" 130 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" 131 | dependencies: 132 | boolbase "~1.0.0" 133 | 134 | parchment@1.1.0: 135 | version "1.1.0" 136 | resolved "https://registry.yarnpkg.com/parchment/-/parchment-1.1.0.tgz#c79387a80fc4af4ba8947b94fc55a835f62850a5" 137 | 138 | quill-delta@3.5.0: 139 | version "3.5.0" 140 | resolved "https://registry.yarnpkg.com/quill-delta/-/quill-delta-3.5.0.tgz#5b67e685da60c34eabed4449c416c74aab89157b" 141 | dependencies: 142 | deep-equal "^1.0.1" 143 | extend "^3.0.0" 144 | fast-diff "1.1.1" 145 | 146 | quill-render@^1.0.5: 147 | version "1.0.5" 148 | resolved "https://registry.yarnpkg.com/quill-render/-/quill-render-1.0.5.tgz#532870df74cd9ae8992a3ea194f1c86ab494a2dc" 149 | dependencies: 150 | cheerio "^0.19.0" 151 | escape-html "^1.0.3" 152 | 153 | quill@^1.3.0: 154 | version "1.3.0" 155 | resolved "https://registry.yarnpkg.com/quill/-/quill-1.3.0.tgz#1fa485dcd0f4c45925ed32158f50d8129ccab134" 156 | dependencies: 157 | clone "~2.1.1" 158 | deep-equal "~1.0.1" 159 | eventemitter3 "~2.0.3" 160 | extend "~3.0.1" 161 | parchment "1.1.0" 162 | quill-delta "3.5.0" 163 | 164 | readable-stream@1.1: 165 | version "1.1.13" 166 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" 167 | dependencies: 168 | core-util-is "~1.0.0" 169 | inherits "~2.0.1" 170 | isarray "0.0.1" 171 | string_decoder "~0.10.x" 172 | 173 | string_decoder@~0.10.x: 174 | version "0.10.31" 175 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 176 | --------------------------------------------------------------------------------