comand-component-library 3.3.84 → 3.3.86

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.
Files changed (38) hide show
  1. package/dist/comand-component-library.js +5623 -3929
  2. package/dist/comand-component-library.umd.cjs +4 -4
  3. package/dist/style.css +1 -1
  4. package/package.json +2 -2
  5. package/src/App.vue +215 -112
  6. package/src/assets/data/component-structure.json +228 -0
  7. package/src/assets/data/form-elements.json +156 -0
  8. package/src/assets/data/opening-hours.json +79 -37
  9. package/src/components/CmdAddressData.vue +187 -201
  10. package/src/components/CmdAddressDataItem.vue +306 -0
  11. package/src/components/CmdBox.vue +1 -0
  12. package/src/components/CmdBoxWrapper.vue +53 -5
  13. package/src/components/CmdFancyBox.vue +31 -4
  14. package/src/components/CmdForm.vue +98 -4
  15. package/src/components/CmdFormElement.vue +5 -1
  16. package/src/components/CmdHeadline.vue +179 -52
  17. package/src/components/CmdImage.vue +205 -76
  18. package/src/components/CmdImageGallery.vue +88 -85
  19. package/src/components/CmdListOfLinks.vue +63 -43
  20. package/src/components/CmdListOfLinksItem.vue +97 -0
  21. package/src/components/CmdLoginForm.vue +3 -6
  22. package/src/components/CmdMultistepFormProgressBar.vue +37 -8
  23. package/src/components/CmdOpeningHours.vue +280 -63
  24. package/src/components/CmdOpeningHoursItem.vue +264 -0
  25. package/src/components/{CmdPager.vue → CmdPagination.vue} +2 -2
  26. package/src/components/CmdSlideshow.vue +137 -10
  27. package/src/components/CmdSocialNetworks.vue +115 -28
  28. package/src/components/CmdSocialNetworksItem.vue +184 -0
  29. package/src/components/CmdTable.vue +0 -1
  30. package/src/components/CmdTextImageBlock.vue +158 -0
  31. package/src/components/CmdThumbnailScroller.vue +132 -12
  32. package/src/components/CmdToggleDarkMode.vue +58 -1
  33. package/src/components/EditComponentWrapper.vue +553 -0
  34. package/src/index.js +2 -2
  35. package/src/mixins/EditMode.vue +28 -9
  36. package/src/utils/editmode.js +30 -5
  37. package/src/components/CmdTextBlock.vue +0 -73
  38. package/src/editmode/editModeContext.js +0 -50
@@ -0,0 +1,264 @@
1
+ <template>
2
+ <!-- begin opening-days and -hours -->
3
+ <template v-if="!editing">
4
+ <dt class="cmd-opening-hours-item">{{ day.day }}</dt>
5
+ <dd>
6
+ <span v-if="day.am" class="am">
7
+ <template v-if="day.am.displayText">{{ day.am.displayText }}</template>
8
+ <template
9
+ v-else>{{ getTime(day.am.fromTime) }} {{ separator }} {{
10
+ getTime(day.am.tillTime)
11
+ }}</template>
12
+ </span>
13
+ <span v-if="day.pm" class="pm">
14
+ <template v-if="day.pm.displayText">{{ day.pm.displayText }}</template>
15
+ <template
16
+ v-else>{{ getTime(day.pm.fromTime) }} {{ separator }} {{
17
+ getTime(day.pm.tillTime)
18
+ }}</template>
19
+ </span>
20
+ </dd>
21
+ </template>
22
+ <!-- end opening-days and -hours -->
23
+
24
+ <!-- begin edit-mode -->
25
+ <template v-else>
26
+ <!-- begin day -->
27
+ <dt>
28
+ <CmdFormElement
29
+ element="input"
30
+ type="text"
31
+ class="edit-mode"
32
+ :showLabel="false"
33
+ labelText="Text for weekday"
34
+ placeholder="Text for weekday"
35
+ v-model="editableDay.day"
36
+ />
37
+ </dt>
38
+ <!-- end day -->
39
+
40
+ <!-- begin hours -->
41
+ <dd class="flex-container no-flex">
42
+ <!-- begin AM -->
43
+ <div class="flex-container no-flex am-wrapper">
44
+ <template v-if="editableDay.amClosed">
45
+ <CmdFormElement
46
+ element="input"
47
+ type="text"
48
+ class="edit-mode"
49
+ :showLabel="false"
50
+ labelText="Text for 'closed'"
51
+ placeholder="Text for 'closed'"
52
+ v-model="editableDay.amDisplayText"
53
+ />
54
+ </template>
55
+ <div v-if="!editableDay.amClosed" class="input-wrapper">
56
+ <CmdFormElement
57
+ element="input"
58
+ type="time"
59
+ class="edit-mode"
60
+ :showLabel="false"
61
+ labelText="Text for AM from"
62
+ placeholder="Text for AM from"
63
+ v-model="editableDay.amFrom"
64
+ />
65
+ <CmdFormElement
66
+ element="input"
67
+ type="time"
68
+ :showLabel="false"
69
+ class="edit-mode"
70
+ :min="editableDay.amFrom"
71
+ labelText="Text for AM till"
72
+ placeholder="Text for AM till"
73
+ v-model="editableDay.amTill"
74
+ />
75
+ </div>
76
+ <a href="#"
77
+ @click.prevent="toggleClosedStatus('am')"
78
+ :title="editableDay.amClosed ? 'Set to open' : 'Set to closed'"
79
+ :class="editableDay.amClosed ? 'icon-clock' : 'icon-blocked'"
80
+ ></a>
81
+ </div>
82
+ <!-- end AM -->
83
+
84
+ <!-- begin PM -->
85
+ <div class="flex-container no-flex pm-wrapper">
86
+ <template v-if="editableDay.pmClosed">
87
+ <CmdFormElement
88
+ element="input"
89
+ type="text"
90
+ class="edit-mode"
91
+ :showLabel="false"
92
+ labelText="Text for 'closed'"
93
+ placeholder="Text for 'closed'"
94
+ v-model="editableDay.pmDisplayText"
95
+ />
96
+ </template>
97
+ <div v-if="!editableDay.pmClosed" class="input-wrapper">
98
+ <CmdFormElement
99
+ element="input"
100
+ type="time"
101
+ :showLabel="false"
102
+ class="edit-mode"
103
+ labelText="Text for PM from"
104
+ placeholder="Text for PM from"
105
+ v-model="editableDay.pmFrom"
106
+ />
107
+ <CmdFormElement
108
+ element="input"
109
+ type="time"
110
+ :showLabel="false"
111
+ class="edit-mode"
112
+ :min="editableDay.pmFrom"
113
+ labelText="Text for PM till"
114
+ placeholder="Text for PM till"
115
+ v-model="editableDay.pmTill"
116
+ />
117
+ </div>
118
+ <a href="#"
119
+ @click.prevent="toggleClosedStatus('pm')"
120
+ :title="editableDay.pmClosed ? 'Set to open' : 'Set to closed'"
121
+ :class="editableDay.pmClosed ? 'icon-clock' : 'icon-blocked'"
122
+ ></a>
123
+ </div>
124
+ <!-- end PM -->
125
+ </dd>
126
+ <!-- end hours -->
127
+ </template>
128
+ <!-- end edit-mode -->
129
+ </template>
130
+
131
+ <script>
132
+ import EditMode from "../mixins/EditMode.vue"
133
+ import {updateHandlerProvider} from "../utils/editmode.js"
134
+
135
+ function timeFormatting(separator, suffix1, suffix2, hoursLeadingZero = true) {
136
+ function addLeadingZero(time, addLeadingZero) {
137
+ if (addLeadingZero && time < 10) {
138
+ return "0" + time
139
+ }
140
+ return time
141
+ }
142
+
143
+ return (hour, minute) => {
144
+ if (suffix2) {
145
+ let hour12 = hour
146
+ let currentSuffix = suffix1
147
+ if (hour12 > 12) {
148
+ hour12 -= 12
149
+ currentSuffix = suffix2
150
+ }
151
+ return addLeadingZero(hour12, hoursLeadingZero) + separator + addLeadingZero(minute, true) + currentSuffix
152
+ }
153
+ return addLeadingZero(hour, hoursLeadingZero) + separator + addLeadingZero(minute, true) + suffix1
154
+ }
155
+ }
156
+
157
+ export default {
158
+ name: "CmdOpeningHoursItem",
159
+ mixins: [EditMode],
160
+ data() {
161
+ return {
162
+ editableDay: {}
163
+ }
164
+ },
165
+ props: {
166
+ /**
167
+ * list of opening-hours
168
+ */
169
+ day: {
170
+ type: Object,
171
+ required: true
172
+ },
173
+ /**
174
+ * separator for time-spans
175
+ */
176
+ separator: {
177
+ type: String,
178
+ default: "–"
179
+ },
180
+ /**
181
+ * abbreviation text for 'hours' (as a unit after displayed times)
182
+ */
183
+ abbreviationText: {
184
+ type: String,
185
+ default: "h"
186
+ },
187
+ /**
188
+ * option to set custom time format by function
189
+ */
190
+ timeFormatter: {
191
+ type: Function,
192
+ required: false
193
+ }
194
+ },
195
+ methods: {
196
+ toggleClosedStatus(period) {
197
+ period === 'am' ? this.editableDay.amClosed = !this.editableDay.amClosed : this.editableDay.pmClosed = !this.editableDay.pmClosed
198
+ },
199
+ getTime(time) {
200
+ if (this.timeFormatter) {
201
+ return this.timeFormatter(time.hours, time.mins)
202
+ }
203
+ return timeFormatting(":", " " + this.abbreviationText, "", false)(time.hours, time.mins)
204
+ },
205
+ updateHandlerProvider() {
206
+ const data = this.editableDay
207
+ return updateHandlerProvider(this, {
208
+ update(props) {
209
+ props.day = data.day
210
+ if (!props.am) {
211
+ props.am = {}
212
+ }
213
+ props.am.fromTime = data.amFrom
214
+ props.am.tillTime = data.amTill
215
+ props.am.displayText = data.amClosed ? data.amDisplayText : ""
216
+ if (!props.pm) {
217
+ props.pm = {}
218
+ }
219
+ props.pm.fromTime = data.pmFrom
220
+ props.pm.tillTime = data.pmTill
221
+ props.pm.displayText = data.pmClosed ? data.pmDisplayText : ""
222
+ }
223
+ })
224
+ }
225
+ },
226
+ watch: {
227
+ day: {
228
+ handler() {
229
+ const timeFormatter = timeFormatting(":", "", "", true)
230
+ this.editableDay = {
231
+ day: this.day.day,
232
+ amFrom: timeFormatter(this.day.am.fromTime.hours, this.day.am.fromTime.mins),
233
+ amTill: timeFormatter(this.day.am.tillTime.hours, this.day.am.tillTime.mins),
234
+ amDisplayText: this.day.am.displayText,
235
+ amClosed: !!this.day.am.displayText,
236
+ pmFrom: timeFormatter(this.day.pm.fromTime.hours, this.day.pm.fromTime.mins),
237
+ pmTill: timeFormatter(this.day.pm.tillTime.hours, this.day.pm.tillTime.mins),
238
+ pmClosed: !!this.day.pm.displayText,
239
+ pmDisplayText: this.day.pm.displayText
240
+ }
241
+ },
242
+ immediate: true,
243
+ deep: true
244
+ }
245
+ }
246
+ }
247
+ </script>
248
+
249
+ <style lang="scss">
250
+ .edit-mode-opening-hours-item {
251
+ .am-wrapper, .pm-wrapper {
252
+ align-items: center;
253
+ gap: calc(var(--default-gap) / 2);
254
+ }
255
+
256
+ label {
257
+ max-width: 11rem;
258
+ }
259
+
260
+ .input-wrapper {
261
+ width: 11rem;
262
+ }
263
+ }
264
+ </style>
@@ -166,7 +166,7 @@ export default {
166
166
  </script>
167
167
 
168
168
  <style lang="scss">
169
- /* begin cmd-pager ---------------------------------------------------------------------------------------- */
169
+ /* begin cmd-pagination ---------------------------------------------------------------------------------------- */
170
170
  @import '../assets/styles/variables';
171
171
 
172
172
  .cmd-pager {
@@ -233,5 +233,5 @@ export default {
233
233
  }
234
234
  }
235
235
 
236
- /* end cmd-pager ------------------------------------------------------------------------------------------ */
236
+ /* end cmd-pagination ------------------------------------------------------------------------------------------ */
237
237
  </style>
@@ -3,8 +3,11 @@
3
3
  <div class="inner-slideshow-wrapper" @mouseenter="pause = true" @mouseleave="pause = false">
4
4
  <!-- begin CmdSlideButton -->
5
5
  <CmdSlideButton
6
+ v-if="showSlideButtons"
6
7
  @click.prevent="showPrevItem"
7
8
  slideButtonType="prev"
9
+ :class="{'disabled': slideshowItemEditing}"
10
+ v-bind="tooltipForSlidebuttons"
8
11
  />
9
12
  <!-- end CmdSlideButton -->
10
13
 
@@ -12,19 +15,34 @@
12
15
  <transition-group name="fade">
13
16
  <template v-if="currentItem">
14
17
  <template v-if="!useSlot">
15
- <a v-if="currentItem?.link?.href" :href="currentItem?.link?.href" :title="currentItem?.link?.tooltip" :key="index">
18
+ <template v-if="!editModeContext">
19
+ <a v-if="currentItem?.link?.href" :href="currentItem?.link?.href"
20
+ :title="currentItem?.link?.tooltip">
16
21
  <!-- begin CmdImage -->
17
22
  <CmdImage :image="currentItem?.image" :figcaption="currentItem?.figcaption"/>
18
23
  <!-- begin CmdImage -->
19
24
  </a>
20
25
 
21
26
  <!-- begin CmdImage -->
22
- <CmdImage v-else :image="currentItem?.image" :figcaption="currentItem?.figcaption" :key="index"/>
27
+ <CmdImage v-else :image="currentItem?.image" :figcaption="currentItem?.figcaption"/>
28
+ <!-- begin CmdImage -->
29
+ </template>
30
+
31
+ <!-- begin edit-mode view -->
23
32
  <!-- begin CmdImage -->
33
+ <CmdImage
34
+ v-else-if="slideshowItems.length"
35
+ :image="currentItem?.image"
36
+ :figcaption="currentItem?.figcaption"
37
+ :componentPath="['props', 'slideshowItems', index]"
38
+ :editModeConfig="imageStructure()"
39
+ />
40
+ <!-- end CmdImage -->
41
+ <!-- end edit-mode view -->
24
42
  </template>
25
43
  <div
26
44
  v-else
27
- class="image-wrapper"
45
+ class="slot-wrapper"
28
46
  :key="index"
29
47
  :style="'background-image: url(' + currentItem.image.srcLarge + ')'"
30
48
  >
@@ -33,35 +51,54 @@
33
51
  <!-- end slot -->
34
52
  </div>
35
53
  </template>
54
+ <button v-else-if="editModeContext" type="button" class="button confirm" @click="onAddItem">
55
+ <span class="icon-plus"></span>
56
+ <span>Add new slideshow-image</span>
57
+ </button>
36
58
  </transition-group>
37
59
  <!-- end area to slide -->
38
60
 
39
61
  <!-- begin CmdSlideButton -->
40
62
  <CmdSlideButton
63
+ v-if="showSlideButtons"
41
64
  @click.prevent="showNextItem"
65
+ :class="{'disabled': slideshowItemEditing}"
66
+ v-bind="tooltipForSlidebuttons"
42
67
  />
43
68
  <!-- end CmdSlideButton -->
44
69
 
45
70
  <ol v-if="showQuickLinkIcons">
46
71
  <li v-for="(item, i) in slideshowItems" :key="i" :class="{active: i === index }">
47
- <a href="#" @click.prevent="index = i" :aria-label="index"></a>
72
+ <a href="#"
73
+ :class="{'disabled': slideshowItemEditing}"
74
+ @click.prevent="showItem(i)"
75
+ :aria-label="index"
76
+ :title="slideshowItemEditing ? 'Not allowed while editing!' : 'Switch to image #' + (i + 1)"
77
+ >
78
+ </a>
48
79
  </li>
49
80
  </ol>
50
- <span v-if="showCounter">{{ index + 1 }}/{{ slideshowItems.length }}</span>
81
+ <span class="item-counter" v-if="showCounter">{{ index + 1 }}/{{ slideshowItems.length }}</span>
51
82
  </div>
52
83
  </div>
53
84
  </template>
54
85
 
55
86
  <script>
87
+ // import mixins
88
+ import EditMode from "../mixins/EditMode.vue"
89
+ import {buildComponentPath, updateHandlerProvider} from "../utils/editmode.js"
90
+ import {createUuid} from "../utils/common.js"
56
91
  export default {
57
92
  name: "CmdSlideshow",
93
+ mixins: [EditMode],
58
94
  data() {
59
95
  return {
60
96
  index: 0,
61
97
  pause: false,
62
98
  hnd: null,
63
99
  fullWidth: false,
64
- currentSlotItem: 0
100
+ currentSlotItem: 0,
101
+ slideshowItemEditing: false
65
102
  }
66
103
  },
67
104
  props: {
@@ -107,9 +144,18 @@ export default {
107
144
  type: Array,
108
145
  required: true
109
146
  },
147
+ /**
148
+ * toggle slide-buttons-visibility
149
+ */
150
+ showSlideButtons: {
151
+ type: Boolean,
152
+ default: false
153
+ },
110
154
  /**
111
155
  * properties for CmdSlideButtons-component
112
156
  *
157
+ * showSlideButtons-property must be activated
158
+ *
113
159
  * @requiredForAccessibility: partial
114
160
  */
115
161
  cmdSlideButtons: {
@@ -140,7 +186,50 @@ export default {
140
186
  }
141
187
  },
142
188
  methods: {
189
+ itemProvider() {
190
+ return {
191
+ "image": {
192
+ "src": {
193
+ "large": "/media/images/slideshow-images/large/slide1.jpg",
194
+ "medium": "/media/images/slideshow-images/medium/slide1.jpg",
195
+ "small": "/media/images/slideshow-images/small/slide1.jpg"
196
+ },
197
+ "alt": "Alternative Text",
198
+ "tooltip": "Tooltip DE"
199
+ },
200
+ "figcaption": {
201
+ "text": "Figcaption DE",
202
+ "position": "bottom",
203
+ "textAlign": "center",
204
+ "show": true
205
+ }
206
+ }
207
+ },
208
+ onAddItem() {
209
+ this.editModeContext.content.addContent(
210
+ buildComponentPath(this, 'props', 'slideshowItems', -1),
211
+ this.itemProvider)
212
+ },
213
+ imageStructure() {
214
+ return {
215
+ itemProviderOverwrite: () => ({
216
+ "image": {
217
+ "src": {
218
+ "large": "/media/images/slideshow-images/large/slide1.jpg",
219
+ "medium": "/media/images/slideshow-images/medium/slide1.jpg",
220
+ "small": "/media/images/slideshow-images/small/slide1.jpg"
221
+ },
222
+ "tooltip": "Tooltip DE"
223
+ }
224
+ })
225
+ }
226
+ },
143
227
  showPrevItem() {
228
+ // avoids slide-button to be clicked in edit-mode
229
+ if (this.slideshowItemEditing) {
230
+ return
231
+ }
232
+
144
233
  if (this.useSlot) {
145
234
  if (this.currentSlotItem > 0) {
146
235
  this.currentSlotItem--
@@ -155,11 +244,16 @@ export default {
155
244
  }
156
245
  },
157
246
  showItem(i) {
158
- if (i >= 0 && i < this.slideshowItems.length) {
247
+ if (!this.slideshowItemEditing && i >= 0 && i < this.slideshowItems.length) {
159
248
  this.index = i;
160
249
  }
161
250
  },
162
251
  showNextItem() {
252
+ // avoids slide-button to be clicked in edit-mode
253
+ if (this.slideshowItemEditing) {
254
+ return
255
+ }
256
+
163
257
  if (this.useSlot) {
164
258
  if (this.currentSlotItem < Object.keys(this.$slots).length - 1) {
165
259
  this.currentSlotItem++
@@ -183,6 +277,15 @@ export default {
183
277
 
184
278
  /* computed property to get current slide */
185
279
  computed: {
280
+ tooltipForSlidebuttons() {
281
+ if (this.slideshowItemEditing) {
282
+ return {
283
+ title: "Not allowed while editing!"
284
+ }
285
+ }
286
+ return {}
287
+ },
288
+ /* computed property to get current slide */
186
289
  currentItem() {
187
290
  if (this.slideshowItems.length <= this.index) {
188
291
  return null
@@ -196,7 +299,15 @@ export default {
196
299
  this.index = 0
197
300
  this.setupSlider()
198
301
  },
199
- immediate: true
302
+ immediate: true,
303
+ deep: true
304
+ },
305
+ currentItem() {
306
+ // wait to nextTick to ensure ref is available
307
+ this.$nextTick(() => {
308
+ this.$refs.slideshowItemComponentWrapper?.addEditStateListener(editing => this.slideshowItemEditing = editing)
309
+ })
310
+
200
311
  }
201
312
  }
202
313
  }
@@ -247,7 +358,7 @@ export default {
247
358
  margin: 0;
248
359
  }
249
360
 
250
- .image-wrapper {
361
+ .slot-wrapper {
251
362
  padding: calc(var(--default-padding) * 5);
252
363
  width: 100%;
253
364
  min-height: 50rem;
@@ -262,6 +373,12 @@ export default {
262
373
  }
263
374
  }
264
375
 
376
+ .image-wrapper {
377
+ width: 100%;
378
+ min-width: 11.1rem; // assure to be as wide as action-buttons in edit-mode
379
+ min-height: 50rem;
380
+ }
381
+
265
382
  > ol {
266
383
  display: -webkit-flex; /* Safari 6-8 */
267
384
  display: flex;
@@ -277,6 +394,7 @@ export default {
277
394
  margin: 0;
278
395
  border: var(--default-border-reduced-opacity);
279
396
  border-radius: var(--full-circle);
397
+ background: var(--light-gray);
280
398
 
281
399
  a {
282
400
  display: block;
@@ -321,7 +439,7 @@ export default {
321
439
  }
322
440
  }
323
441
 
324
- > span {
442
+ > .item-counter {
325
443
  position: absolute;
326
444
  top: .5rem;
327
445
  right: 5.5rem;
@@ -338,5 +456,14 @@ export default {
338
456
  }
339
457
  }
340
458
 
459
+ .edit-mode .cmd-slideshow .image-wrapper.edit-items {
460
+ padding: 0;
461
+ margin-top: 2rem;
462
+
463
+ label.edit-mode input {
464
+ font-size: 3rem;
465
+ }
466
+ }
467
+
341
468
  /* end cmd-slideshow ------------------------------------------------------------------------------------------ */
342
469
  </style>