@fishawack/lab-velocity 0.8.5 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,115 @@
1
+ @import "element-plus/theme-chalk/el-dropdown";
2
+ @import "element-plus/theme-chalk/el-dropdown-item";
3
+ @import "element-plus/theme-chalk/el-dialog";
4
+ @import "./button.scss";
5
+
6
+ .vel-wysiwyg__controls {
7
+ background-color: $color0;
8
+ display: flex;
9
+ flex-grow: 1;
10
+ border: solid $color5 2px;
11
+ border-bottom: none;
12
+ // margin-bottom: .5 * $spacing;
13
+ font-size: get-ratio(14px);
14
+ padding: 0 .5 * $spacing;
15
+ > * {
16
+ padding: .5 * $spacing;
17
+ padding-right: $spacing;
18
+ --el-font-size-base: get-ratio(14px);
19
+ &:not(:last-child) {
20
+ border-right: solid 1px $color5;
21
+ }
22
+ }
23
+
24
+ button {
25
+ // border: solid 1px $color1;
26
+ background-color: transparent;
27
+ cursor: pointer;
28
+ min-width: 28px;
29
+ padding: 3px 5px;
30
+ line-height: 1;
31
+ border: none;
32
+ &.is-active, &:hover {
33
+ background-color: $color5;
34
+ }
35
+ svg {
36
+ height: 90%;
37
+ }
38
+ }
39
+ .el-dropdown {
40
+ line-height: 1.15;
41
+ }
42
+
43
+ .ql-stroke {
44
+ fill: none;
45
+ stroke: #444;
46
+ stroke-linecap: round;
47
+ stroke-linejoin: round;
48
+ stroke-width: 2;
49
+ }
50
+
51
+ .ql-stroke-miter {
52
+ fill: none;
53
+ stroke: #444;
54
+ stroke-miterlimit: 10;
55
+ stroke-width: 2;
56
+ }
57
+
58
+ .ql-fill,
59
+ .ql-stroke.ql-fill {
60
+ fill: #444;
61
+ }
62
+
63
+ .ql-empty {
64
+ fill: none;
65
+ }
66
+
67
+ .ql-even {
68
+ fill-rule: evenodd;
69
+ }
70
+
71
+ .ql-thin,
72
+ .ql-stroke.ql-thin {
73
+ stroke-width: 1;
74
+ }
75
+
76
+ .ql-transparent {
77
+ opacity: 0.4;
78
+ }
79
+
80
+ ~ div {
81
+ // margin-top: $spacing;
82
+ border: solid $color5 2px;
83
+ padding: 2 * $spacing;
84
+ background-color: $color0;
85
+ }
86
+ }
87
+ .vel-wysiwyg__button {
88
+ // border: solid 1px $color1;
89
+ background-color: transparent;
90
+ // cursor: pointer;
91
+
92
+ &.is-active, &:hover {
93
+ background-color: $color5;
94
+ }
95
+ }
96
+
97
+ .vel-wysiwyg {
98
+ // border: solid $color1 1px;
99
+ // padding: $spacing * 1.5;
100
+
101
+ table,td,th {
102
+ border: solid .5px $color1;
103
+ }
104
+ th {
105
+ background-color: $color5;
106
+ }
107
+ hr {
108
+ height: 1px;
109
+ background-color: $color1;
110
+ }
111
+ a {
112
+ text-decoration: underline;
113
+ }
114
+ }
115
+
@@ -0,0 +1,341 @@
1
+ <template>
2
+ <XInput v-bind="$props" class="vel-wysiwyg">
3
+ <template #label>
4
+ <slot name="label" />
5
+ </template>
6
+ <div class="control-group vel-wysiwyg__controls" v-if="editor">
7
+ <el-dropdown>
8
+ Heading
9
+ <template #dropdown>
10
+ <el-dropdown-menu>
11
+ <el-dropdown-item @click="editor.chain().focus().toggleHeading({ level: 1 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 1 }) }">
12
+ H1
13
+ </el-dropdown-item>
14
+ <el-dropdown-item @click="editor.chain().focus().toggleHeading({ level: 2 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 2 }) }">
15
+ H2
16
+ </el-dropdown-item>
17
+ <el-dropdown-item @click="editor.chain().focus().toggleHeading({ level: 3 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 3 }) }">
18
+ H3
19
+ </el-dropdown-item>
20
+ <el-dropdown-item @click="editor.chain().focus().toggleHeading({ level: 4 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 4 }) }">
21
+ H4
22
+ </el-dropdown-item>
23
+ <el-dropdown-item @click="editor.chain().focus().toggleHeading({ level: 5 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 5 }) }">
24
+ H5
25
+ </el-dropdown-item>
26
+ <el-dropdown-item @click="editor.chain().focus().toggleHeading({ level: 6 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 6 }) }">
27
+ H6
28
+ </el-dropdown-item>
29
+ <el-dropdown-item @click="editor.chain().focus().setParagraph().run()" :class="{ 'is-active': editor.isActive('paragraph') }">
30
+ Paragraph
31
+ </el-dropdown-item>
32
+ </el-dropdown-menu>
33
+ </template>
34
+ </el-dropdown>
35
+ <el-dropdown>
36
+ Style
37
+ <template #dropdown>
38
+ <el-dropdown-menu>
39
+ <el-dropdown-item class="vel-wysiwyg__button" @click="editor.chain().focus().toggleBold().run()" :disabled="!editor.can().chain().focus().toggleBold().run()" :class="{ 'is-active': editor.isActive('bold') }">Bold</el-dropdown-item>
40
+ <el-dropdown-item class="vel-wysiwyg__button" @click="editor.chain().focus().toggleItalic().run()" :disabled="!editor.can().chain().focus().toggleItalic().run()" :class="{ 'is-active': editor.isActive('italic') }">Italic</el-dropdown-item>
41
+ <el-dropdown-item class="vel-wysiwyg__button" @click="editor.chain().focus().toggleUnderline().run()" :disabled="!editor.can().chain().focus().toggleUnderline().run()" :class="{ 'is-active': editor.isActive('underline') }">Underline</el-dropdown-item>
42
+ </el-dropdown-menu>
43
+ </template>
44
+ </el-dropdown>
45
+ <el-dropdown v-if="table">
46
+ Table
47
+ <template #dropdown>
48
+ <el-dropdown-menu>
49
+ <el-dropdown-item>
50
+ <button type="button" @click="editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()">
51
+ Insert table
52
+ </button>
53
+ </el-dropdown-item>
54
+ <el-dropdown-item>
55
+ <button type="button" @click="editor.chain().focus().addColumnBefore().run()">
56
+ Add column before
57
+ </button>
58
+ </el-dropdown-item>
59
+ <el-dropdown-item>
60
+ <button type="button" @click="editor.chain().focus().addColumnAfter().run()">
61
+ Add column after
62
+ </button>
63
+ </el-dropdown-item>
64
+ <el-dropdown-item>
65
+ <button type="button" @click="editor.chain().focus().deleteColumn().run()">
66
+ Delete column
67
+ </button>
68
+ </el-dropdown-item>
69
+ <el-dropdown-item>
70
+ <button type="button" @click="editor.chain().focus().addRowBefore().run()">
71
+ Add row before
72
+ </button>
73
+ </el-dropdown-item>
74
+ <el-dropdown-item>
75
+ <button type="button" @click="editor.chain().focus().addRowAfter().run()">
76
+ Add row after
77
+ </button>
78
+ </el-dropdown-item>
79
+ <el-dropdown-item>
80
+ <button type="button" @click="editor.chain().focus().deleteRow().run()">
81
+ Delete row
82
+ </button>
83
+ </el-dropdown-item>
84
+ <el-dropdown-item>
85
+ <button type="button" @click="editor.chain().focus().deleteTable().run()">
86
+ Delete table
87
+ </button>
88
+ </el-dropdown-item>
89
+ <el-dropdown-item>
90
+ <button type="button" @click="editor.chain().focus().mergeCells().run()">
91
+ Merge cells
92
+ </button>
93
+ </el-dropdown-item>
94
+ <el-dropdown-item>
95
+ <button type="button" @click="editor.chain().focus().splitCell().run()">
96
+ Split cell
97
+ </button>
98
+ </el-dropdown-item>
99
+ <el-dropdown-item>
100
+ <button type="button" @click="editor.chain().focus().toggleHeaderColumn().run()">
101
+ Toggle header column
102
+ </button>
103
+ </el-dropdown-item>
104
+ <el-dropdown-item>
105
+ <button type="button" @click="editor.chain().focus().toggleHeaderRow().run()">
106
+ Toggle header row
107
+ </button>
108
+ </el-dropdown-item>
109
+ <el-dropdown-item>
110
+ <button type="button" @click="editor.chain().focus().toggleHeaderCell().run()">
111
+ Toggle header cell
112
+ </button>
113
+ </el-dropdown-item>
114
+ <el-dropdown-item>
115
+ <button type="button" @click="editor.chain().focus().mergeOrSplit().run()">
116
+ Merge or split
117
+ </button>
118
+ </el-dropdown-item>
119
+ <el-dropdown-item>
120
+ <button type="button" @click="editor.chain().focus().setCellAttribute('colspan', 2).run()">
121
+ Set cell attribute
122
+ </button>
123
+ </el-dropdown-item>
124
+ <el-dropdown-item>
125
+ <button type="button" @click="editor.chain().focus().fixTables().run()">
126
+ Fix tables
127
+ </button>
128
+ </el-dropdown-item>
129
+ <el-dropdown-item>
130
+ <button type="button" @click="editor.chain().focus().goToNextCell().run()">
131
+ Go to next cell
132
+ </button>
133
+ </el-dropdown-item>
134
+ <el-dropdown-item>
135
+ <button type="button" @click="editor.chain().focus().goToPreviousCell().run()">
136
+ Go to previous cell
137
+ </button>
138
+ </el-dropdown-item>
139
+ </el-dropdown-menu>
140
+ </template>
141
+ </el-dropdown>
142
+ <button type="button" @click="editor.chain().focus().toggleBulletList().run()" :class="{ 'is-active': editor.isActive('bulletList') }">
143
+ <svg viewBox="0 0 18 18"> <line class="ql-stroke" x1="6" x2="15" y1="4" y2="4"></line> <line class="ql-stroke" x1="6" x2="15" y1="9" y2="9"></line> <line class="ql-stroke" x1="6" x2="15" y1="14" y2="14"></line> <line class="ql-stroke" x1="3" x2="3" y1="4" y2="4"></line> <line class="ql-stroke" x1="3" x2="3" y1="9" y2="9"></line> <line class="ql-stroke" x1="3" x2="3" y1="14" y2="14"></line> </svg>
144
+ </button>
145
+ <button type="button" @click="editor.chain().focus().toggleOrderedList().run()" :class="{ 'is-active': editor.isActive('orderedList') }">
146
+ <svg viewBox="0 0 18 18"> <line class="ql-stroke" x1="7" x2="15" y1="4" y2="4"></line> <line class="ql-stroke" x1="7" x2="15" y1="9" y2="9"></line> <line class="ql-stroke" x1="7" x2="15" y1="14" y2="14"></line> <line class="ql-stroke ql-thin" x1="2.5" x2="4.5" y1="5.5" y2="5.5"></line> <path class="ql-fill" d="M3.5,6A0.5,0.5,0,0,1,3,5.5V3.085l-0.276.138A0.5,0.5,0,0,1,2.053,3c-0.124-.247-0.023-0.324.224-0.447l1-.5A0.5,0.5,0,0,1,4,2.5v3A0.5,0.5,0,0,1,3.5,6Z"></path> <path class="ql-stroke ql-thin" d="M4.5,10.5h-2c0-.234,1.85-1.076,1.85-2.234A0.959,0.959,0,0,0,2.5,8.156"></path> <path class="ql-stroke ql-thin" d="M2.5,14.846a0.959,0.959,0,0,0,1.85-.109A0.7,0.7,0,0,0,3.75,14a0.688,0.688,0,0,0,.6-0.736,0.959,0.959,0,0,0-1.85-.109"></path> </svg>
147
+ </button>
148
+ <button type="button" @click="editor.chain().focus().toggleCodeBlock().run()" :class="{ 'is-active': editor.isActive('codeBlock') }">
149
+ Code block
150
+ </button>
151
+ <button type="button" @click="editor.chain().focus().toggleBlockquote().run()" :class="{ 'is-active': editor.isActive('blockquote') }">
152
+ Blockquote
153
+ </button>
154
+ <button type="button" @click="editor.chain().focus().setHorizontalRule().run()">
155
+ Horizontal rule
156
+ </button>
157
+ <button type="button" @click="editor.chain().focus().toggleSuperscript().run()" :class="{ 'is-active': editor.isActive('superscript') }">
158
+ <svg viewBox="0 0 18 18"> <path class="ql-fill" d="M15.5,7H13.861a4.015,4.015,0,0,0,1.914-2.975,1.8,1.8,0,0,0-1.6-1.751A1.922,1.922,0,0,0,12.021,3.7a0.5,0.5,0,1,0,.957.291,0.917,0.917,0,0,1,1.053-.725,0.81,0.81,0,0,1,.744.762c0,1.077-1.164,1.925-1.934,2.486A1.423,1.423,0,0,0,12,7.5a0.5,0.5,0,0,0,.5.5h3A0.5,0.5,0,0,0,15.5,7Z"></path> <path class="ql-fill" d="M9.651,5.241a1,1,0,0,0-1.41.108L6,7.964,3.759,5.349a1,1,0,1,0-1.519,1.3L4.683,9.5,2.241,12.35a1,1,0,1,0,1.519,1.3L6,11.036,8.241,13.65a1,1,0,0,0,1.519-1.3L7.317,9.5,9.759,6.651A1,1,0,0,0,9.651,5.241Z"></path> </svg>
159
+ </button>
160
+ <button type="button" @click="editor.chain().focus().toggleSubscript().run()" :class="{ 'is-active': editor.isActive('subscript') }">
161
+ <svg viewBox="0 0 18 18"> <path class="ql-fill" d="M15.5,15H13.861a3.858,3.858,0,0,0,1.914-2.975,1.8,1.8,0,0,0-1.6-1.751A1.921,1.921,0,0,0,12.021,11.7a0.50013,0.50013,0,1,0,.957.291h0a0.914,0.914,0,0,1,1.053-.725,0.81,0.81,0,0,1,.744.762c0,1.076-1.16971,1.86982-1.93971,2.43082A1.45639,1.45639,0,0,0,12,15.5a0.5,0.5,0,0,0,.5.5h3A0.5,0.5,0,0,0,15.5,15Z"></path> <path class="ql-fill" d="M9.65,5.241a1,1,0,0,0-1.409.108L6,7.964,3.759,5.349A1,1,0,0,0,2.192,6.59178Q2.21541,6.6213,2.241,6.649L4.684,9.5,2.241,12.35A1,1,0,0,0,3.71,13.70722q0.02557-.02768.049-0.05722L6,11.036,8.241,13.65a1,1,0,1,0,1.567-1.24277Q9.78459,12.3777,9.759,12.35L7.316,9.5,9.759,6.651A1,1,0,0,0,9.65,5.241Z"></path> </svg>
162
+ </button>
163
+ <button type="button" @click="setLink" :class="{ 'is-active': editor.isActive('link') }">
164
+ <svg viewBox="0 0 18 18"> <line class="ql-stroke" x1="7" x2="11" y1="7" y2="11"></line> <path class="ql-even ql-stroke" d="M8.9,4.577a3.476,3.476,0,0,1,.36,4.679A3.476,3.476,0,0,1,4.577,8.9C3.185,7.5,2.035,6.4,4.217,4.217S7.5,3.185,8.9,4.577Z"></path> <path class="ql-even ql-stroke" d="M13.423,9.1a3.476,3.476,0,0,0-4.679-.36,3.476,3.476,0,0,0,.36,4.679c1.392,1.392,2.5,2.542,4.679.36S14.815,10.5,13.423,9.1Z"></path> </svg>
165
+ </button>
166
+ </div>
167
+ <editor-content :editor="editor" />
168
+ <el-dialog
169
+ v-model="dialogVisible"
170
+ title="URL"
171
+ width="500"
172
+ >
173
+ <label>Enter URL</label>
174
+ <el-input v-model="newUrl" type="url" />
175
+ <template #footer>
176
+ <div class="dialog-footer">
177
+ <el-button @click="dialogVisible = false">Cancel</el-button>
178
+ <el-button type="primary" @click="updateURL">
179
+ Confirm
180
+ </el-button>
181
+ </div>
182
+ </template>
183
+ </el-dialog>
184
+ </XInput>
185
+ </template>
186
+
187
+ <script>
188
+ import input from "./input.js";
189
+ import XInput from "./input.vue";
190
+ import sanitizeHtml from 'sanitize-html';
191
+ import { ElDropdown, ElDropdownItem, ElDropdownMenu, ElDialog, ElButton, ElInput } from "element-plus";
192
+ import { Editor, EditorContent } from '@tiptap/vue-3'
193
+ import StarterKit from '@tiptap/starter-kit';
194
+ import Underline from '@tiptap/extension-underline'
195
+ import Table from '@tiptap/extension-table'
196
+ import TableCell from '@tiptap/extension-table-cell'
197
+ import TableHeader from '@tiptap/extension-table-header'
198
+ import TableRow from '@tiptap/extension-table-row'
199
+ import Superscript from '@tiptap/extension-superscript'
200
+ import Subscript from '@tiptap/extension-subscript'
201
+ import Link from '@tiptap/extension-link'
202
+
203
+ export default {
204
+ mixins: [input],
205
+
206
+ components: {
207
+ XInput,
208
+ EditorContent,
209
+ ElDropdown,
210
+ ElDropdownItem,
211
+ ElDropdownMenu,
212
+ ElDialog,
213
+ ElButton,
214
+ ElInput
215
+ },
216
+
217
+ props: {
218
+ table: {
219
+ type: Boolean,
220
+ default: false,
221
+ },
222
+ baseClass: {
223
+ type: String,
224
+ default: "vel-wysiwyg",
225
+ },
226
+ },
227
+
228
+ data: () => ({
229
+ editor: null,
230
+ hold: null,
231
+ previousUrl: null,
232
+ newUrl: null,
233
+ dialogVisible:false,
234
+ }),
235
+
236
+ watch: {
237
+ modelValue: {
238
+ handler(val) {
239
+ if (this.hold !== val) {
240
+ this.setValue();
241
+ }
242
+ },
243
+ },
244
+ },
245
+
246
+ methods: {
247
+ setValue() {
248
+ const temp =
249
+ this.simple && this.modelValue // Surround text in p tags to keep it grouped correctly on simple strings. Ignore if modelValue empty otherwise you'll end up with <p>null</p>
250
+ ? `<p>${this.modelValue}</p>`
251
+ : this.modelValue;
252
+ this.editor.commands.setContent(temp);
253
+ this.hold = temp;
254
+
255
+
256
+ },
257
+ // Function to remove p tags from inside li tags, breaks the wysiwyg
258
+ formatCleaner(unformmatted) {
259
+ if(!unformmatted) {
260
+ return "";
261
+ }
262
+ let parser = document.createElement('div');
263
+ parser.innerHTML = unformmatted.replace(/(\r\n|\n|\r|\t)/gm,"");
264
+ const lists = parser.getElementsByTagName('ul');
265
+ for(var x = 0; x < lists.length; x++) {
266
+ lists[x].innerHTML = sanitizeHtml(lists[x].innerHTML, {
267
+ allowedTags: [ 'b', 'i', 'em', 'strong', 'a','li']
268
+ });
269
+ }
270
+ return parser.innerHTML;
271
+ },
272
+ setLink() {
273
+ this.previousUrl = this.editor.getAttributes('link').href;
274
+ this.newUrl = this.previousUrl;
275
+ this.dialogVisible = true;
276
+
277
+ },
278
+ updateURL() {
279
+ // cancelled
280
+ this.dialogVisible = false;
281
+ let url = this.newUrl;
282
+ if (url === this.previousUrl) {
283
+ return
284
+ }
285
+
286
+ // empty
287
+ if (url === '') {
288
+ this.editor
289
+ .chain()
290
+ .focus()
291
+ .extendMarkRange('link')
292
+ .unsetLink()
293
+ .run()
294
+
295
+ return
296
+ }
297
+ // update link
298
+ this.editor
299
+ .chain()
300
+ .focus()
301
+ .extendMarkRange('link')
302
+ .setLink({ href: url })
303
+ .run()
304
+ }
305
+ },
306
+
307
+ mounted() {
308
+ let extensions = [
309
+ StarterKit,
310
+ Underline,
311
+ Superscript,
312
+ Subscript,
313
+ Link.configure({
314
+ openOnClick: false,
315
+ defaultProtocol: 'https',
316
+ })
317
+ ];
318
+ if(this.$props.table) {
319
+ extensions.push(
320
+ Table.configure({
321
+ resizable: true,
322
+ }),
323
+ TableRow,
324
+ TableHeader,
325
+ TableCell);
326
+ }
327
+
328
+ this.editor = new Editor({
329
+ extensions: extensions,
330
+ });
331
+ this.setValue();
332
+
333
+ this.editor.on('blur', ({ editor, event }) => {
334
+ if(this.hold !== event.srcElement.innerHTML) {
335
+ this.hold = event.srcElement.innerHTML;
336
+ this.$emit("update:modelValue", this.hold);
337
+ }
338
+ })
339
+ },
340
+ };
341
+ </script>
package/general.scss CHANGED
@@ -13,6 +13,7 @@
13
13
  @import "./components/_link.scss";
14
14
  @import "./components/_cascader.scss";
15
15
  @import "./components/_wysiwyg.scss";
16
+ @import "./components/_wysiwyg2.scss";
16
17
  @import "./components/_upload.scss";
17
18
  @import "./components/_inputNumber.scss";
18
19
 
package/index.js CHANGED
@@ -10,6 +10,7 @@ export { default as file } from "./form/file.vue";
10
10
  export { default as Select } from "./form/Select.vue";
11
11
  export { default as Switch } from "./form/Switch.vue";
12
12
  export { default as Wysiwyg } from "./form/Wysiwyg.vue";
13
+ export { default as Wysiwyg2 } from "./form/Wysiwyg2.vue";
13
14
  export { default as Upload } from "./form/Upload.vue";
14
15
  export { default as InputNumber } from "./form/InputNumber.vue";
15
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishawack/lab-velocity",
3
- "version": "0.8.5",
3
+ "version": "0.8.7",
4
4
  "description": "Avalere Health branded style system",
5
5
  "scripts": {
6
6
  "setup": "npm ci || npm i && npm run content",
@@ -40,6 +40,17 @@
40
40
  "vuex-persistedstate": "^4.1.0"
41
41
  },
42
42
  "dependencies": {
43
+ "@tiptap/extension-link": "^2.11.2",
44
+ "@tiptap/extension-subscript": "^2.11.2",
45
+ "@tiptap/extension-superscript": "^2.11.2",
46
+ "@tiptap/extension-table": "^2.11.2",
47
+ "@tiptap/extension-table-cell": "^2.11.2",
48
+ "@tiptap/extension-table-header": "^2.11.2",
49
+ "@tiptap/extension-table-row": "^2.11.2",
50
+ "@tiptap/extension-underline": "^2.11.2",
51
+ "@tiptap/pm": "^2.11.2",
52
+ "@tiptap/starter-kit": "^2.11.2",
53
+ "@tiptap/vue-3": "^2.11.2",
43
54
  "element-plus": "^2.7.8",
44
55
  "quill": "^1.3.7",
45
56
  "sanitize-html": "^2.13.1"