comand-component-library 3.3.76 → 3.3.78

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.
@@ -1,74 +1,32 @@
1
1
  <template>
2
2
  <!-- begin edit-mode -->
3
- <figure v-if="editModeContext?.editing" :class="['cmd-image flex-container vertical', getTextAlign]">
4
- <CmdFormElement
5
- element="input"
6
- type="checkbox"
7
- :toggleSwitch="true"
8
- labelText="Show figcaption"
9
- v-model="editableShowFigcaption"
10
- />
11
- <CmdFormElement
12
- element="select"
13
- labelText="Figcaption Position"
14
- :selectOptions="positionOptions"
15
- :disabled="!showFigcaption"
16
- v-model="editableFigcaptionPosition"
17
- />
18
- <CmdFormElement
19
- element="select"
20
- labelText="Figcaption text alignment"
21
- :selectOptions="textAlignOptions"
22
- :disabled="!showFigcaption"
23
- v-model="editableFigcaptionTextAlign"
24
- />
25
- <CmdFormElement element="input" type="text" :required="true" labelText="Alternative Text"
26
- v-model="editableAlternativeText"/>
27
- <CmdFormElement element="input" type="text" :required="false" labelText="Tooltip" v-model="editableTooltip"/>
28
-
3
+ <figure v-if="editing" :class="['cmd-image flex-container vertical', getTextAlign]">
29
4
  <template v-if="figcaption?.position === 'top'">
30
- <CmdFormElement element="input" type="text" :required="true" labelText="Text figcaption"
31
- v-model="editableFigcaptionText"/>
5
+ <CmdFormElement
6
+ element="input"
7
+ type="text"
8
+ :required="true"
9
+ labelText="Text figcaption"
10
+ v-model="editableFigcaptionText"
11
+ />
32
12
  </template>
33
13
  <div :class="['box drop-area flex-container vertical', { 'allow-drop': allowDrop }]" v-on="dragAndDropHandler" title="Drag new image to this area to replace old one!">
34
14
  <span class="icon-image"></span>
35
- <img ref="contentImage" :src="image.src" :alt="image.alt" :title="image.tooltip"/>
15
+ <img :src="imageSource" :alt="image.alt" :title="image.tooltip"/>
36
16
  </div>
37
- <button
38
- type="button"
39
- :class="['button upload primary', { disabled: uploadInitiated }]"
40
- :disabled="uploadInitiated"
41
- @click="selectFiles()"
42
- >
43
- <!-- begin CmdIcon -->
44
- <CmdIcon iconClass="icon-loop"/>
45
- <!-- end CmdIcon -->
46
- <span>Select image</span>
47
- </button>
17
+
48
18
  <template v-if="figcaption?.position !== 'top'">
49
19
  <CmdFormElement
50
- element="input"
51
- type="text"
52
- :class="getTextAlign"
53
- :required="true"
54
- labelText="Text figcaption"
55
- v-model="editableFigcaptionText"
20
+ element="input"
21
+ type="text"
22
+ :class="getTextAlign"
23
+ :required="true"
24
+ labelText="Text figcaption"
25
+ :showLabel="false"
26
+ v-model="editableFigcaptionText"
56
27
  />
57
28
  </template>
58
29
  </figure>
59
-
60
- <!-- begin CmdFormElement -->
61
- <CmdFormElement
62
- v-if="editModeContext?.editing"
63
- class="hidden"
64
- element="input"
65
- type="file"
66
- labelText="Select file"
67
- :disabled="uploadInitiated"
68
- @change="fileSelected"
69
- ref="formElement"
70
- />
71
- <!-- end CmdFormElement -->
72
30
  <!-- end edit-mode -->
73
31
 
74
32
  <figure v-else :class="['cmd-image', getTextAlign]">
@@ -79,21 +37,19 @@
79
37
  </template>
80
38
 
81
39
  <script>
82
- import {getFileExtension} from "../utils/getFileExtension"
40
+ import {checkAndUploadFile} from "../utils/checkAndUploadFile"
41
+ import EditMode from "../mixins/EditMode.vue"
42
+ import {updateHandlerProvider} from "../utils/editmode.js"
83
43
 
84
44
  export default {
85
45
  name: "CmdImage",
86
- inject: {
87
- editModeContext: {
88
- default: null
89
- }
90
- },
46
+ mixins: [EditMode],
91
47
  data() {
92
48
  return {
93
49
  mediumMaxWidth: 1023,
94
50
  smallMaxWidth: 600,
95
51
  currentWindowWidth: window.innerWidth,
96
- allowedFileExtensions: ["jpg", "jpeg", "png"],
52
+ allowedFileExtensions: ["jpg", "jpeg", "png", "webp"],
97
53
  uploadInitiated: false,
98
54
  allowDrop: false,
99
55
  showFigcaption: true,
@@ -101,6 +57,7 @@ export default {
101
57
  figcaptionTextAlign: null,
102
58
  tooltip: null,
103
59
  alternativeText: null,
60
+ newImageSource: null,
104
61
  positionOptions: [
105
62
  {
106
63
  text: "Above image",
@@ -128,13 +85,7 @@ export default {
128
85
  figcaptionText: null
129
86
  }
130
87
  },
131
- mounted() {
132
- this.editModeContext?.addSaveHandler(this.onSave)
133
- },
134
88
  props: {
135
- editModeContextData: {
136
- type: Object
137
- },
138
89
  /**
139
90
  * image-object including source, alternative text, tooltip (not required)
140
91
  */
@@ -158,7 +109,7 @@ export default {
158
109
  },
159
110
  minImageWidth: {
160
111
  type: Number,
161
- default: 1025
112
+ default: 600
162
113
  }
163
114
  },
164
115
  created() {
@@ -175,6 +126,11 @@ export default {
175
126
  },
176
127
  computed: {
177
128
  imageSource() {
129
+ // check if a new image is provided
130
+ if(this.newImageSource) {
131
+ return this.newImageSource
132
+ }
133
+
178
134
  // if only one src exists
179
135
  const imgSrc = this.image.src
180
136
 
@@ -194,6 +150,12 @@ export default {
194
150
  // else return large (will be used if images for small-and -medium-devices do not exist or if screen resolution is larger than mediumMaxWidth)
195
151
  return imgSrc.large
196
152
  },
153
+ getTextAlign() {
154
+ if (this.figcaption?.textAlign) {
155
+ return "text-" + this.figcaption.textAlign
156
+ }
157
+ return ''
158
+ },
197
159
  dragAndDropHandler() {
198
160
  // register handlers only if drag-and-drop is enabled
199
161
  return {
@@ -203,55 +165,9 @@ export default {
203
165
  drop: this.drop
204
166
  }
205
167
  },
206
- getTextAlign() {
207
- if (this.figcaption?.textAlign) {
208
- return "text-" + this.figcaption.textAlign
209
- }
210
- return ''
211
- },
212
- editableAlternativeText: {
213
- get() {
214
- return this.alternativeText == null ? this.image.alt : this.alternativeText
215
- },
216
- set(value) {
217
- this.alternativeText = value
218
- }
219
- },
220
- editableTooltip: {
221
- get() {
222
- return this.tooltip == null ? this.image.tooltip : this.tooltip
223
- },
224
- set(value) {
225
- this.tooltip = value
226
- }
227
- },
228
- editableShowFigcaption: {
229
- get() {
230
- return this.showFigcaption == null ? this.figcaption.show : this.showFigcaption
231
- },
232
- set(value) {
233
- this.showFigcaption = value
234
- }
235
- },
236
- editableFigcaptionPosition: {
237
- get() {
238
- return this.figcaptionPosition == null ? this.figcaption.position : this.figcaptionPosition
239
- },
240
- set(value) {
241
- this.figcaptionPosition = value
242
- }
243
- },
244
- editableFigcaptionTextAlign: {
245
- get() {
246
- return this.figcaptionTextAlign || this.figcaption.textAlign
247
- },
248
- set(value) {
249
- this.figcaptionTextAlign = value
250
- }
251
- },
252
168
  editableFigcaptionText: {
253
169
  get() {
254
- return this.figcaptionText || this.figcaption.text
170
+ return this.figcaptionText == null ? this.figcaption.text : this.figcaptionText
255
171
  },
256
172
  set(value) {
257
173
  this.figcaptionText = value
@@ -273,15 +189,6 @@ export default {
273
189
  }
274
190
  }
275
191
  },
276
- fileSelected(event) {
277
- if (event.target.files.length > 0) {
278
- this.checkAndUploadFile(event.target.files[0])
279
- }
280
- },
281
- selectFiles() {
282
- let inputFile = this.$refs.formElement.getDomElement().querySelector("input[type='file']")
283
- inputFile.click()
284
- },
285
192
  dragEnter(event) {
286
193
  this.dragOver(event)
287
194
  },
@@ -306,80 +213,40 @@ export default {
306
213
  this.allowDrop = false
307
214
  if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) {
308
215
  event.preventDefault()
309
- this.checkAndUploadFile(event.dataTransfer.files[0])
216
+ checkAndUploadFile(event.dataTransfer.files[0], this.allowedFileExtensions, this.minImageWidth, this.maxFileUploadSize, (imageSource) => this.newImageSource = imageSource)
310
217
  }
311
218
  },
312
- onSave() {
313
- const data = {
314
- image: {
315
- alt: this.editableAlternativeText,
316
- tooltip: this.editableTooltip
219
+ addHandlerProvider() {
220
+ const itemStructure = {
221
+ "image": {
222
+ "id": createUuid(),
223
+ "src": "media/images/demo-images/large/landscape-06.jpg",
224
+ "srcImageLarge": "media/images/demo-images/large/landscape-06.jpg",
225
+ "alt": "Alternative Text"
317
226
  },
318
- figcaption: {
319
- position: this.editableFigcaptionPosition,
320
- textAlign: this.editableFigcaptionTextAlign,
321
- text: this.editableFigcaptionText,
322
- show: this.editableShowFigcaption
227
+ "figcaption": {
228
+ "show": true,
229
+ "position": "bottom",
230
+ "text": "Figcaption",
231
+ "textAlign": "center"
323
232
  }
324
233
  }
325
- return {
326
- editModeContextData: this.editModeContextData,
327
- ...data,
234
+ return updateHandlerProvider(this, {
235
+ item() {
236
+ return itemStructure
237
+ }
238
+ })
239
+ },
240
+ updateHandlerProvider() {
241
+ const figcaptionText = this.editableFigcaptionText
242
+ return updateHandlerProvider(this, {
328
243
  update(props) {
329
- console.log("CmdImage.update", props)
330
- if (!props.image) {
331
- props.image = {}
332
- }
333
- props.image.alt = data.image.alt
334
- props.image.tooltip = data.image.tooltip
335
244
  if (!props.figcaption) {
336
245
  props.figcaption = {}
337
246
  }
338
- props.figcaption.position = data.figcaption.position
339
- props.figcaption.textAlign = data.figcaption.textAlign
340
- props.figcaption.text = data.figcaption.text
341
- props.figcaption.show = data.figcaption.show
247
+ props.figcaption.text = figcaptionText
342
248
  }
343
- }
344
- },
345
- checkAndUploadFile(file) {
346
- const errorMessages = []
347
-
348
- // check size for current file
349
- if (file.size > this.maxFileUploadSize) {
350
- errorMessages.push("file too large")
351
- }
352
-
353
- // check if current file has allowed file-type
354
- if (!this.allowedFileExtensions.includes(getFileExtension(file.name))) {
355
- errorMessages.push("disallowed file extension")
356
- }
357
-
358
- if (errorMessages.length) {
359
- alert(errorMessages)
360
- return
361
- }
362
-
363
- // check for min dimensions
364
- const image = new Image()
365
-
366
- image.onload = () => {
367
- if (image.width < this.minImageWidth) {
368
- // errorMessages.push("width (" + image.width + " px) too small - at least " + this.minImageWidth + " px required!")
369
- const confirmUpload = confirm("width (" + image.width + " px) too small - at least " + this.minImageWidth + " px required! Use trotzdem!")
370
- if (!confirmUpload) {
371
- alert("Abbruch")
372
- return
373
- }
374
- }
375
- // revoke URL to clean memory
376
- URL.revokeObjectURL(image.src)
377
-
378
- // show preview-image by assigning image.src (containing image date (not its path) to do existing contentImage source
379
- this.$refs.contentImage.src = image.src
380
- }
381
- // create data-url (contains content of a file (not its path))
382
- image.src = URL.createObjectURL(file)
249
+ })
383
250
  }
384
251
  }
385
252
  }
@@ -388,6 +255,10 @@ export default {
388
255
  <style lang="scss">
389
256
  /* begin cmd-image ------------------------------------------------------------------------------------------ */
390
257
  .cmd-image {
258
+ img {
259
+ display: block;
260
+ }
261
+
391
262
  &.text-center {
392
263
  figcaption {
393
264
  text-align: center;
@@ -430,4 +301,4 @@ export default {
430
301
  }
431
302
 
432
303
  /* end cmd-image ------------------------------------------------------------------------------------------ */
433
- </style>
304
+ </style>
@@ -0,0 +1,29 @@
1
+ <script>
2
+ import {findEditComponentWrapper} from "../utils/editmode.js"
3
+
4
+ export default {
5
+ inject: {
6
+ editModeContext: {
7
+ default: null
8
+ }
9
+ },
10
+ data() {
11
+ return {
12
+ editing: false
13
+ }
14
+ },
15
+ created() {
16
+ const editComponentWrapper = findEditComponentWrapper(this.$parent)
17
+ if (editComponentWrapper) {
18
+ editComponentWrapper.addEditStateListener(editing => this.editing = editing)
19
+ editComponentWrapper.addUpdateHandlerProvider(this.updateHandlerProvider)
20
+ editComponentWrapper.setAddHandlerProvider(this.addHandlerProvider)
21
+ }
22
+ },
23
+ methods: {
24
+ updateHandlerProvider() {
25
+ return {}
26
+ }
27
+ }
28
+ }
29
+ </script>
@@ -0,0 +1,48 @@
1
+ import {getFileExtension} from "./getFileExtension.js"
2
+
3
+ function checkAndUploadFile(file, allowedFileExtensions, minImageWidth, maxFileUploadSize, imagePreview) {
4
+ const errorMessages = []
5
+
6
+ // check size for current file
7
+ if (file.size > maxFileUploadSize) {
8
+ errorMessages.push("file too large")
9
+ }
10
+
11
+ // check if current file has allowed file-type
12
+ if (!allowedFileExtensions.includes(getFileExtension(file.name))) {
13
+ errorMessages.push("disallowed file extension")
14
+ }
15
+
16
+ if (errorMessages.length) {
17
+ alert(errorMessages)
18
+ return
19
+ }
20
+
21
+ // check for min dimensions
22
+ const image = new Image()
23
+
24
+ image.onload = () => {
25
+ if (image.width < minImageWidth) {
26
+ // errorMessages.push("width (" + image.width + " px) too small - at least " + this.minImageWidth + " px required!")
27
+ const confirmUpload = confirm("width (" + image.width + " px) too small - at least " + minImageWidth + " px required! Use trotzdem!")
28
+ if (!confirmUpload) {
29
+ alert("Cancel")
30
+ return
31
+ }
32
+ }
33
+ // revoke URL to clean memory
34
+ URL.revokeObjectURL(image.src)
35
+
36
+ // show preview-image by assigning image.src (containing image date (not its path) to do existing contentImage source
37
+ if(typeof imagePreview === "function") {
38
+ imagePreview(image.src)
39
+ } else {
40
+ imagePreview.src = image.src
41
+ }
42
+
43
+ }
44
+ // create data-url (contains content of a file (not its path))
45
+ image.src = URL.createObjectURL(file)
46
+ }
47
+
48
+ export { checkAndUploadFile }
@@ -0,0 +1,42 @@
1
+ function findEditComponentWrapper(component) {
2
+ if (component?.$options?.name === "EditComponentWrapper") {
3
+ return component
4
+ }
5
+ if (component?.$parent) {
6
+ return findEditComponentWrapper(component.$parent)
7
+ }
8
+ return null
9
+ }
10
+
11
+ function buildComponentPath(component, ...extraPathElements) {
12
+ const path = []
13
+ for (let parent = findEditComponentWrapper(component); parent; parent = findEditComponentWrapper(parent.$parent)) {
14
+ path.unshift(...parent.componentPath)
15
+ }
16
+ path.push(...extraPathElements)
17
+ return path
18
+ }
19
+
20
+ function componentPathAsString(componentPath) {
21
+ if (Array.isArray(componentPath) && componentPath.length > 0) {
22
+ return JSON.stringify(componentPath)
23
+ }
24
+ return ""
25
+ }
26
+
27
+ function updateHandlerProvider(component, options) {
28
+ if (component?.$options?.name) {
29
+ return {
30
+ name: component.$options.name,
31
+ ...options
32
+ }
33
+ }
34
+ return options
35
+ }
36
+
37
+ export {
38
+ findEditComponentWrapper,
39
+ buildComponentPath,
40
+ componentPathAsString,
41
+ updateHandlerProvider
42
+ }