@afeefa/vue-app 0.0.91 → 0.0.93
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.
- package/.afeefa/package/release/version.txt +1 -1
- package/package.json +1 -1
- package/src/components/ARichTextArea.vue +74 -16
- package/src/components/form/fields/FormFieldRichTextArea.vue +5 -1
- package/src/services/escape/CascadingWindowEventDispatcher.js +4 -0
- package/src-admin/components/form/RemoveButton.vue +7 -3
- package/src-admin/config/vuetify.js +6 -4
- package/src-admin/styles.scss +9 -0
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.93
|
package/package.json
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
<template>
|
2
|
-
<div :class="['a-rich-text-editor a-text-input', {'a-text-input-focused':
|
2
|
+
<div :class="['a-rich-text-editor a-text-input', {'a-text-input-focused': editorFocus}]">
|
3
3
|
<div
|
4
4
|
v-if="editor"
|
5
5
|
class="menu-bar"
|
@@ -7,7 +7,8 @@
|
|
7
7
|
<div>
|
8
8
|
<v-btn
|
9
9
|
small
|
10
|
-
:class="['menu-button', {'is-active':
|
10
|
+
:class="['menu-button', {'is-active': editorFocus && editor.isActive('bold')}]"
|
11
|
+
title="fett"
|
11
12
|
@click="editor.chain().focus().toggleBold().run()"
|
12
13
|
>
|
13
14
|
<v-icon>{{ boldIcon }}</v-icon>
|
@@ -15,7 +16,8 @@
|
|
15
16
|
|
16
17
|
<v-btn
|
17
18
|
small
|
18
|
-
:class="['menu-button', {'is-active':
|
19
|
+
:class="['menu-button', {'is-active': editorFocus && editor.isActive('italic')}]"
|
20
|
+
title="kursiv"
|
19
21
|
@click="editor.chain().focus().toggleItalic().run()"
|
20
22
|
>
|
21
23
|
<v-icon>{{ italicIcon }}</v-icon>
|
@@ -23,7 +25,8 @@
|
|
23
25
|
|
24
26
|
<v-btn
|
25
27
|
small
|
26
|
-
:class="['menu-button', 'strike', {'is-active':
|
28
|
+
:class="['menu-button', 'strike', {'is-active': editorFocus && editor.isActive('strike')}]"
|
29
|
+
title="durchgestrichen"
|
27
30
|
@click="editor.chain().focus().toggleStrike().run()"
|
28
31
|
>
|
29
32
|
<v-icon>{{ strikeIcon }}</v-icon>
|
@@ -31,7 +34,8 @@
|
|
31
34
|
|
32
35
|
<v-btn
|
33
36
|
small
|
34
|
-
:class="['menu-button', {'is-active':
|
37
|
+
:class="['menu-button', {'is-active': editorFocus && editor.isActive('heading', {level: 1})}]"
|
38
|
+
title="überschrift 1"
|
35
39
|
@click="editor.chain().focus().toggleHeading({level: 1}).run()"
|
36
40
|
>
|
37
41
|
<v-icon>{{ h1Icon }}</v-icon>
|
@@ -39,7 +43,8 @@
|
|
39
43
|
|
40
44
|
<v-btn
|
41
45
|
small
|
42
|
-
:class="['menu-button', {'is-active':
|
46
|
+
:class="['menu-button', {'is-active': editorFocus && editor.isActive('heading', {level: 2})}]"
|
47
|
+
title="pberschrift 2"
|
43
48
|
@click="editor.chain().focus().toggleHeading({level: 2}).run()"
|
44
49
|
>
|
45
50
|
<v-icon>{{ h2Icon }}</v-icon>
|
@@ -47,7 +52,8 @@
|
|
47
52
|
|
48
53
|
<v-btn
|
49
54
|
small
|
50
|
-
:class="['menu-button', {'is-active':
|
55
|
+
:class="['menu-button', {'is-active': editorFocus && editor.isActive('bulletList')}]"
|
56
|
+
title="punkt-liste"
|
51
57
|
@click="editor.chain().focus().toggleBulletList().run()"
|
52
58
|
>
|
53
59
|
<v-icon>{{ ulIcon }}</v-icon>
|
@@ -55,7 +61,8 @@
|
|
55
61
|
|
56
62
|
<v-btn
|
57
63
|
small
|
58
|
-
:class="['menu-button', {'is-active':
|
64
|
+
:class="['menu-button', {'is-active': editorFocus && editor.isActive('orderedList')}]"
|
65
|
+
title="nummerierte liste"
|
59
66
|
@click="editor.chain().focus().toggleOrderedList().run()"
|
60
67
|
>
|
61
68
|
<v-icon>{{ olIcon }}</v-icon>
|
@@ -63,7 +70,8 @@
|
|
63
70
|
|
64
71
|
<v-btn
|
65
72
|
small
|
66
|
-
:class="['menu-button', {'is-active':
|
73
|
+
:class="['menu-button', {'is-active': editorFocus && editor.isActive('blockquote')}]"
|
74
|
+
title="zitat"
|
67
75
|
@click="editor.chain().focus().toggleBlockquote().run()"
|
68
76
|
>
|
69
77
|
<v-icon>{{ commentIcon }}</v-icon>
|
@@ -72,13 +80,37 @@
|
|
72
80
|
<v-btn
|
73
81
|
small
|
74
82
|
class="menu-button"
|
83
|
+
:class="{ 'is-active': editorFocus && editorSelectionIs('#0000FF')}"
|
84
|
+
title="blau"
|
85
|
+
color="blue--text"
|
86
|
+
@click="editorSelectionIs('#0000FF') ? editor.chain().focus().unsetColor().run() : editor.chain().focus().setColor('#0000FF').run()"
|
87
|
+
>
|
88
|
+
<v-icon>$paletteIcon</v-icon>
|
89
|
+
</v-btn>
|
90
|
+
|
91
|
+
<v-btn
|
92
|
+
small
|
93
|
+
class="menu-button"
|
94
|
+
:class="{ 'is-active': editorFocus && editorSelectionIs('#FF0000')}"
|
95
|
+
title="rot"
|
96
|
+
color="red--text"
|
97
|
+
@click="editorSelectionIs('#FF0000') ? editor.chain().focus().unsetColor().run() : editor.chain().focus().setColor('#FF0000').run()"
|
98
|
+
>
|
99
|
+
<v-icon>$paletteIcon</v-icon>
|
100
|
+
</v-btn>
|
101
|
+
|
102
|
+
<v-btn
|
103
|
+
small
|
104
|
+
class="menu-button undo-button"
|
75
105
|
:disabled="initialValue === editor.getHTML()"
|
106
|
+
title="rückgängig"
|
76
107
|
@click="editor.chain().focus().undo().run()"
|
77
108
|
>
|
78
109
|
<v-icon>{{ undoIcon }}</v-icon>
|
79
110
|
</v-btn>
|
80
111
|
</div>
|
81
112
|
|
113
|
+
|
82
114
|
<div>
|
83
115
|
<slot name="buttons" />
|
84
116
|
</div>
|
@@ -86,7 +118,7 @@
|
|
86
118
|
|
87
119
|
<editor-content
|
88
120
|
:editor="editor"
|
89
|
-
:class="['a-rich-text-editor', {
|
121
|
+
:class="['a-rich-text-editor', {editorFocus}]"
|
90
122
|
/>
|
91
123
|
</div>
|
92
124
|
</template>
|
@@ -108,9 +140,11 @@ import {
|
|
108
140
|
mdiRotateLeft,
|
109
141
|
mdiRotateRight
|
110
142
|
} from '@mdi/js'
|
143
|
+
import { Color } from '@tiptap/extension-color'
|
144
|
+
import TextStyle from '@tiptap/extension-text-style'
|
111
145
|
|
112
146
|
@Component({
|
113
|
-
props: ['value', 'validator'],
|
147
|
+
props: ['value', 'validator', 'focus'],
|
114
148
|
components: {
|
115
149
|
EditorContent
|
116
150
|
}
|
@@ -119,7 +153,7 @@ export default class ARichTextArea extends Vue {
|
|
119
153
|
editor = null
|
120
154
|
internalValue = null
|
121
155
|
initialValue = null
|
122
|
-
|
156
|
+
editorFocus = false
|
123
157
|
|
124
158
|
boldIcon = mdiFormatBold
|
125
159
|
italicIcon = mdiFormatItalic
|
@@ -137,25 +171,34 @@ export default class ARichTextArea extends Vue {
|
|
137
171
|
this.internalValue = this.value
|
138
172
|
}
|
139
173
|
|
174
|
+
changed () {
|
175
|
+
console.log('Changed')
|
176
|
+
}
|
177
|
+
|
140
178
|
mounted () {
|
179
|
+
this.editorFocus = !!this.focus
|
180
|
+
|
141
181
|
if (this.validator) {
|
142
182
|
this.$refs.input.validate(true)
|
143
183
|
}
|
144
184
|
|
145
185
|
this.editor = new Editor({
|
146
186
|
content: this.internalValue,
|
187
|
+
autofocus: this.focus ? 'end' : false,
|
147
188
|
extensions: [
|
148
|
-
StarterKit
|
189
|
+
StarterKit,
|
190
|
+
TextStyle,
|
191
|
+
Color
|
149
192
|
],
|
150
193
|
onUpdate: () => {
|
151
194
|
this.$emit('input', this.editor.getHTML())
|
152
195
|
},
|
153
196
|
onFocus: ({ editor, event }) => {
|
154
|
-
this.
|
197
|
+
this.editorFocus = true
|
155
198
|
this.$emit('focus')
|
156
199
|
},
|
157
200
|
onBlur: ({ editor, event }) => {
|
158
|
-
this.
|
201
|
+
this.editorFocus = false
|
159
202
|
this.$emit('blur')
|
160
203
|
}
|
161
204
|
})
|
@@ -165,6 +208,10 @@ export default class ARichTextArea extends Vue {
|
|
165
208
|
this.editor.destroy()
|
166
209
|
}
|
167
210
|
|
211
|
+
editorSelectionIs (color) {
|
212
|
+
return this.editor.isActive('textStyle', { color: color })
|
213
|
+
}
|
214
|
+
|
168
215
|
/**
|
169
216
|
* reset the text area to disable the undo button
|
170
217
|
* e.g. after saving the form while keeping it open
|
@@ -180,6 +227,10 @@ export default class ARichTextArea extends Vue {
|
|
180
227
|
const isSame = this.editor.getHTML() === this.internalValue
|
181
228
|
if (!isSame) {
|
182
229
|
this.editor.commands.setContent(this.internalValue, false)
|
230
|
+
// witch reusing the editor component, we need to restore the focus state
|
231
|
+
if (this.focus && this.focus === true) {
|
232
|
+
this.editor.commands.focus('end')
|
233
|
+
}
|
183
234
|
}
|
184
235
|
}
|
185
236
|
|
@@ -240,11 +291,18 @@ export default class ARichTextArea extends Vue {
|
|
240
291
|
width: unset;
|
241
292
|
}
|
242
293
|
|
294
|
+
&:disabled {
|
295
|
+
background: none !important;
|
296
|
+
:deep(*) {
|
297
|
+
color: #CCCCCC !important;
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
243
301
|
&.is-active {
|
244
302
|
background: #ECECEC !important;
|
245
303
|
}
|
246
304
|
|
247
|
-
|
305
|
+
&.menu-button:disabled {
|
248
306
|
background: none !important;
|
249
307
|
}
|
250
308
|
}
|
@@ -10,6 +10,10 @@ class CascadingWindowEventDispatcher {
|
|
10
10
|
addEventListener (event, listener) {
|
11
11
|
if (!this.listeners[event]) {
|
12
12
|
this.listeners[event] = []
|
13
|
+
}
|
14
|
+
|
15
|
+
if (!this.listeners[event].length) {
|
16
|
+
this.listeners[event] = []
|
13
17
|
|
14
18
|
window.addEventListener(event, e => {
|
15
19
|
for (const listener of this.listeners[event]) {
|
@@ -4,14 +4,14 @@
|
|
4
4
|
<v-btn
|
5
5
|
:class="'a-btn-standard removeButton-' + dialogId"
|
6
6
|
fab
|
7
|
-
small
|
8
7
|
:color="(hover ? 'red' : 'grey lighten-3')"
|
9
8
|
:title="title"
|
9
|
+
v-bind="{ small: isSmall, ...$attrs}"
|
10
10
|
@click="remove"
|
11
11
|
>
|
12
12
|
<v-icon
|
13
13
|
class="white--hover"
|
14
|
-
size="1.3rem"
|
14
|
+
:size="iconSize || '1.3rem'"
|
15
15
|
>
|
16
16
|
$trashCanIcon
|
17
17
|
</v-icon>
|
@@ -44,13 +44,17 @@ import { DialogEvent } from '@a-vue/events'
|
|
44
44
|
import { randomCssClass } from '@a-vue/utils/random'
|
45
45
|
|
46
46
|
@Component({
|
47
|
-
props: ['title', 'message', 'info', 'itemTitle', 'protect']
|
47
|
+
props: ['iconSize', 'title', 'message', 'info', 'itemTitle', 'protect']
|
48
48
|
})
|
49
49
|
export default class EditPage extends Vue {
|
50
50
|
dialogId = randomCssClass(10)
|
51
51
|
removeKey = null
|
52
52
|
removeConfirmed = null
|
53
53
|
|
54
|
+
get isSmall () {
|
55
|
+
return Object.keys(this.$attrs).filter(k => k.match(/x-small|default|large|x-large/)).length === 0
|
56
|
+
}
|
57
|
+
|
54
58
|
async remove () {
|
55
59
|
if (this.protect) {
|
56
60
|
this.removeKey = [...Array(6)].map(() => Math.floor(Math.random() * 16).toString(16)).join('')
|
@@ -1,13 +1,14 @@
|
|
1
1
|
import {
|
2
2
|
mdiAlarmLightOutline,
|
3
|
-
mdiArrowLeft,
|
4
3
|
mdiAlert,
|
4
|
+
mdiArrowLeft,
|
5
5
|
mdiCalendar,
|
6
6
|
mdiCheck,
|
7
7
|
mdiCheckBold,
|
8
8
|
mdiChevronRight,
|
9
9
|
mdiClose,
|
10
10
|
mdiCloseThick,
|
11
|
+
mdiCurrencyEur,
|
11
12
|
mdiDelete,
|
12
13
|
mdiDotsHorizontal,
|
13
14
|
mdiDotsVertical,
|
@@ -16,11 +17,11 @@ import {
|
|
16
17
|
mdiMagnify,
|
17
18
|
mdiMenuDown,
|
18
19
|
mdiMenuUp,
|
20
|
+
mdiPalette,
|
19
21
|
mdiPencil,
|
20
22
|
mdiPlus,
|
21
23
|
mdiPrinter,
|
22
|
-
mdiThumbUpOutline
|
23
|
-
mdiCurrencyEur
|
24
|
+
mdiThumbUpOutline
|
24
25
|
} from '@mdi/js'
|
25
26
|
import Vue from 'vue'
|
26
27
|
import Vuetify from 'vuetify/lib'
|
@@ -52,7 +53,8 @@ export default new Vuetify({
|
|
52
53
|
caretDownIcon: mdiMenuDown,
|
53
54
|
caretUpIcon: mdiMenuUp,
|
54
55
|
printerIcon: mdiPrinter,
|
55
|
-
euroSymbol: mdiCurrencyEur
|
56
|
+
euroSymbol: mdiCurrencyEur,
|
57
|
+
paletteIcon: mdiPalette
|
56
58
|
}
|
57
59
|
},
|
58
60
|
breakpoint: {
|
package/src-admin/styles.scss
CHANGED
@@ -59,6 +59,10 @@
|
|
59
59
|
opacity: .08;
|
60
60
|
}
|
61
61
|
|
62
|
+
.theme--light.v-input .error--text {
|
63
|
+
color: #616161 !important;
|
64
|
+
}
|
65
|
+
|
62
66
|
.theme--light.v-btn.v-btn--disabled,
|
63
67
|
.theme--light.v-btn.v-btn--disabled span,
|
64
68
|
.theme--light.v-btn.v-btn--disabled .v-icon,
|
@@ -66,6 +70,11 @@
|
|
66
70
|
color: white !important;
|
67
71
|
}
|
68
72
|
|
73
|
+
.theme--light.v-btn:focus-visible {
|
74
|
+
outline: 2px solid #1976d2;
|
75
|
+
}
|
76
|
+
|
77
|
+
|
69
78
|
.theme--light.v-btn.v-btn--disabled.v-btn--has-bg {
|
70
79
|
background-color: #EEEEEE !important;
|
71
80
|
}
|