comand-component-library 3.1.68 → 3.1.71

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 (36) hide show
  1. package/dist/comand-component-library.css +1 -1
  2. package/dist/comand-component-library.umd.min.js +1 -1
  3. package/package.json +2 -2
  4. package/src/App.vue +271 -173
  5. package/src/assets/data/list-of-links.json +0 -1
  6. package/src/assets/fonts/iconfonts/logos-iconfont/icomoon.woff +0 -0
  7. package/src/assets/fonts/iconfonts/logos-iconfont/selection.json +1 -0
  8. package/src/assets/styles/global-styles.scss +56 -48
  9. package/src/assets/styles/logos-iconfont.css +47 -32
  10. package/src/components/CmdBackToTopButton.vue +1 -1
  11. package/src/components/CmdBox.vue +54 -28
  12. package/src/components/CmdBoxSiteSearch.vue +228 -46
  13. package/src/components/CmdCompanyLogo.vue +37 -12
  14. package/src/components/CmdCookieDisclaimer.vue +16 -17
  15. package/src/components/CmdCustomHeadline.vue +1 -1
  16. package/src/components/CmdFakeSelect.vue +24 -28
  17. package/src/components/CmdFormElement.vue +157 -141
  18. package/src/components/CmdInputGroup.vue +132 -4
  19. package/src/components/CmdLoginForm.vue +4 -2
  20. package/src/components/CmdMultipleSwitch.vue +14 -2
  21. package/src/components/CmdMultistepFormProgressBar.vue +2 -2
  22. package/src/components/CmdProgressBar.vue +2 -2
  23. package/src/components/CmdSiteHeader.vue +12 -3
  24. package/src/components/CmdTable.vue +1 -1
  25. package/src/components/CmdTabs.vue +3 -7
  26. package/src/components/CmdThumbnailScroller.vue +1 -1
  27. package/src/components/CmdToggleDarkMode.vue +66 -0
  28. package/src/components/CmdUploadForm.vue +5 -6
  29. package/src/index.js +1 -2
  30. package/src/mixins/CmdFormElement/DefaultMessageProperties.js +1 -1
  31. package/src/mixins/FieldValidation.js +1 -1
  32. package/src/mixins/GlobalDefaultMessageProperties.js +1 -2
  33. package/src/mixins/I18n.js +12 -2
  34. package/src/utils/{GetFileExtension.js → getFileExtension.js} +0 -0
  35. package/src/assets/fonts/iconfonts/logos-iconfont/logos-iconfont.json +0 -1
  36. package/src/components/CmdSwitchButton.vue +0 -181
@@ -1,27 +1,31 @@
1
1
  <template>
2
2
  <!-- begin boxType 'content' -->
3
- <div v-if="boxType === 'content'" :class="['cmd-box box content', {open : open, collapsible: collapsible}]">
3
+ <div v-if="boxType === 'content'" :class="['cmd-box box content', {open : open, collapsible: collapsible, 'stretch-vertically': stretchVertically}]">
4
4
  <template v-if="useSlots?.includes('header')">
5
5
  <!-- begin collapsible header with slot -->
6
- <a v-if="collapsible" href="#" :title="open ? iconOpen.tooltip : iconClosed.tooltip" @click.prevent="toggleContentVisibility">
6
+ <div v-if="collapsible" class="box-header">
7
7
  <!-- begin slot 'header' -->
8
8
  <slot name="header"></slot>
9
9
  <!-- end slot 'header' -->
10
- <span class="toggle-icon" :class="[open ? iconOpen.iconClass : iconClosed.iconClass]"></span>
11
- </a>
10
+ <a href="#"
11
+ :title="open ? iconOpen.tooltip : iconClosed.tooltip"
12
+ @click.prevent="toggleContentVisibility">
13
+ <span class="toggle-icon" :class="[open ? iconOpen.iconClass : iconClosed.iconClass]"></span>
14
+ </a>
15
+ </div>
12
16
  <!-- end collapsible header with slot -->
13
17
 
14
18
  <!-- begin default header with slot -->
15
- <header v-else>
19
+ <div v-else class="box-header">
16
20
  <!-- begin slot 'header' -->
17
21
  <slot name="header"></slot>
18
22
  <!-- end slot 'header' -->
19
- </header>
23
+ </div>
20
24
  <!-- end default header with slot -->
21
25
  </template>
22
26
  <template v-else>
23
27
  <!-- begin header for collapsible -->
24
- <a v-if="collapsible" href="#" :title="open ? iconOpen.tooltip : iconClosed.tooltip" @click.prevent="toggleContentVisibility">
28
+ <a v-if="collapsible" class="box-header" href="#" :title="open ? iconOpen.tooltip : iconClosed.tooltip" @click.prevent="toggleContentVisibility">
25
29
  <!-- begin CmdCustomHeadline -->
26
30
  <CmdCustomHeadline v-if="cmdCustomHeadline?.headlineText"
27
31
  v-bind="cmdCustomHeadline"/>
@@ -32,7 +36,9 @@
32
36
 
33
37
  <!-- begin CmdCustomHeadline -->
34
38
  <CmdCustomHeadline v-else-if="!collapsible && cmdCustomHeadline?.headlineText"
35
- v-bind="cmdCustomHeadline"/>
39
+ class="box-header"
40
+ v-bind="cmdCustomHeadline"
41
+ />
36
42
  <!-- end CmdCustomHeadline -->
37
43
  </template>
38
44
 
@@ -48,17 +54,17 @@
48
54
  </div>
49
55
  <!-- end box-body -->
50
56
 
51
- <footer v-if="useSlots?.includes('footer')">
57
+ <div v-if="useSlots?.includes('footer')" class="box-footer">
52
58
  <!-- begin slot 'footer' -->
53
59
  <slot name="footer"></slot>
54
60
  <!-- end slot 'footer' -->
55
- </footer>
61
+ </div>
56
62
  </div>
57
63
  <!-- end boxType 'content' -->
58
64
 
59
65
  <!-- begin boxType 'product' -->
60
- <a v-else-if="boxType === 'product' && product" class="cmd-box box product" href="#" @click.prevent="clickOnProduct(product)">
61
- <div>
66
+ <a v-else-if="boxType === 'product' && product" :class="['cmd-box box product', {'stretch-vertically': stretchVertically}]" href="#" @click.prevent="clickOnProduct(product)">
67
+ <div class="box-header flex-container vertical">
62
68
  <img v-if="product.image" :src="product.image.src" :alt="product.image.alt"/>
63
69
  <div class="ribbon-new" v-if="product.new">
64
70
  <span>{{ getMessage("cmdbox.productbox.new") }}</span>
@@ -74,15 +80,17 @@
74
80
  </div>
75
81
  <div class="box-body">
76
82
  <p v-if="product.articleNumber">{{ getMessage("cmdbox.productbox.article_no") }} {{ product.articleNumber }}</p>
77
- <p v-if="product.price" class="price"><span>{{ product.price }}</span><span :title="globalCurrency.name">{{ globalCurrency.symbol }}</span></p>
83
+ <p v-if="product.price" class="price">
84
+ <span>{{ product.price }}</span><span :title="globalCurrency.name">{{ globalCurrency.symbol }}</span>
85
+ </p>
78
86
  <p v-if="product.description">{{ product.description }}</p>
79
87
  </div>
80
88
  </a>
81
89
  <!-- end boxType 'product' -->
82
90
 
83
91
  <!-- begin boxType 'user' -->
84
- <div v-else-if="boxType === 'user' && user" class="cmd-box box user">
85
- <div>
92
+ <div v-else-if="boxType === 'user' && user" :class="['cmd-box box user', {'stretch-vertically': stretchVertically}]">
93
+ <div class="box-header">
86
94
  <img v-if="user.image" :src="user.image.src" :alt="user.image.alt"/>
87
95
  <div v-else :class="defaultProfileIconClass" :title="user.name"></div>
88
96
  <!-- begin CmdCustomHeadline -->
@@ -96,9 +104,9 @@
96
104
  <p v-if="user.position">{{ user.position }}</p>
97
105
  <p v-if="user.description" class="description">{{ user.description }}</p>
98
106
  </div>
99
- <footer v-if="user.links">
107
+ <div v-if="user.links" class="box-footer">
100
108
  <CmdListOfLinks :links="user.links" orientation="horizontal" :useGap="false"/>
101
- </footer>
109
+ </div>
102
110
  </div>
103
111
  <!-- end boxType 'user' -->
104
112
  </template>
@@ -233,6 +241,13 @@ export default {
233
241
  }
234
242
  }
235
243
  },
244
+ /**
245
+ * allow box to be stretched as high as parent-element
246
+ */
247
+ stretchVertically: {
248
+ type: Boolean,
249
+ default: true
250
+ },
236
251
  /**
237
252
  * properties for CmdCustomHeadline-component
238
253
  */
@@ -288,18 +303,22 @@ export default {
288
303
  padding: var(--default-padding);
289
304
  }
290
305
 
306
+ &.stretch-vertically {
307
+ height: 100%;
308
+ }
309
+
291
310
  &.content {
292
311
  > * {
293
312
  > *:last-child {
294
313
  margin-bottom: 0;
295
314
  }
296
315
 
297
- &:last-child {
316
+ &:not(.open):last-child {
298
317
  margin-top: auto;
299
318
  }
300
319
  }
301
320
 
302
- > header, > a {
321
+ > .box-header, > a {
303
322
  display: flex;
304
323
  align-items: center;
305
324
  border-top-left-radius: var(--border-radius);
@@ -324,7 +343,7 @@ export default {
324
343
  }
325
344
 
326
345
  .box-body {
327
- height: 100%;
346
+ flex-grow: 1;
328
347
  padding: 0;
329
348
 
330
349
  .padding {
@@ -367,7 +386,7 @@ export default {
367
386
  }
368
387
  }
369
388
 
370
- footer {
389
+ .box-footer {
371
390
  border-bottom-left-radius: var(--border-radius);
372
391
  border-bottom-right-radius: var(--border-radius);
373
392
  padding: var(--default-padding);
@@ -425,7 +444,7 @@ export default {
425
444
  }
426
445
  }
427
446
 
428
- > div:first-child {
447
+ > .box-header {
429
448
  > img, > div {
430
449
  display: table;
431
450
  margin: 0 auto;
@@ -433,6 +452,8 @@ export default {
433
452
  }
434
453
 
435
454
  .box-body {
455
+ flex-grow: 1;
456
+
436
457
  > * {
437
458
  text-align: center;
438
459
  }
@@ -440,6 +461,10 @@ export default {
440
461
  .price {
441
462
  font-size: 2rem;
442
463
  font-weight: bold;
464
+
465
+ span:last-child {
466
+ margin-left: calc(var(--default-margin) / 2);
467
+ }
443
468
  }
444
469
  }
445
470
 
@@ -449,11 +474,10 @@ export default {
449
474
  }
450
475
 
451
476
  &.user {
452
- > div:first-child {
477
+ > .box-header {
453
478
  padding: var(--default-padding);
454
- background: var(--pure-white);
455
479
 
456
- > img, > div {
480
+ > img, > div:first-child {
457
481
  display: table;
458
482
  margin: 0 auto;
459
483
  padding: calc(var(--default-padding) * 3);
@@ -465,6 +489,8 @@ export default {
465
489
  }
466
490
 
467
491
  .box-body {
492
+ flex-grow: 1;
493
+
468
494
  p {
469
495
  text-align: center;
470
496
  font-weight: bold;
@@ -479,13 +505,13 @@ export default {
479
505
  }
480
506
  }
481
507
 
482
- footer {
508
+ .box-footer {
483
509
  margin-top: auto;
484
510
  border-top: var(--default-border);
485
511
 
486
-
487
512
  .cmd-list-of-links {
488
513
  ul {
514
+ width: 100%;
489
515
  margin-bottom: 0;
490
516
 
491
517
  li {
@@ -495,7 +521,7 @@ export default {
495
521
  flex: 1;
496
522
  padding: var(--default-padding);
497
523
  text-align: center;
498
- background: var(--pure-white);
524
+ background: var(--color-scheme-background-color);
499
525
  border-left: var(--default-border);
500
526
  }
501
527
 
@@ -13,52 +13,72 @@
13
13
 
14
14
  <!-- begin form-elements -->
15
15
  <div class="flex-container">
16
- <!-- begin CmdFormElement -->
16
+ <!-- begin CmdFormElement for first input -->
17
17
  <CmdFormElement
18
+ v-if="cmdFormElementInput1.show"
18
19
  element="input"
19
- type="text"
20
- :labelText="getMessage('cmdsitesearch.labeltext.what_to_search')"
21
- :placeholder="getMessage('cmdsitesearch.placeholder.what_to_search')"
20
+ :type="cmdFormElementInput1.type"
21
+ :show-label="cmdFormElementInput1.showLabel"
22
+ :labelText="cmdFormElementInput1.labelText"
23
+ :placeholder="cmdFormElementInput1.placeholder"
24
+ v-model="searchValue1"
22
25
  />
23
- <!-- end CmdFormElement -->
26
+ <!-- end CmdFormElement for first input -->
24
27
 
25
- <!-- begin CmdFormElement -->
26
- <CmdFormElement
27
- element="input"
28
- type="text"
29
- :labelText="getMessage('cmdsitesearch.labeltext.where_to_search')"
30
- :placeholder="getMessage('cmdsitesearch.placeholder.where_to_search')"
31
- />
32
- <!-- end CmdFormElement -->
28
+ <div class="flex-container no-gap">
29
+ <!-- begin CmdFormElement for second input -->
30
+ <CmdFormElement
31
+ v-if="cmdFormElementInput2.show"
32
+ element="input"
33
+ :type="cmdFormElementInput2.type"
34
+ :show-label="cmdFormElementInput2.showLabel"
35
+ :labelText="cmdFormElementInput2.labelText"
36
+ :placeholder="cmdFormElementInput2.placeholder"
37
+ v-model="searchValue2"
38
+ />
39
+ <!-- end CmdFormElement for second input -->
33
40
 
34
- <!-- begin CmdFormElement -->
41
+ <!-- begin CmdFormElement for radius -->
42
+ <CmdFormElement
43
+ v-if="cmdFormElementRadius.show"
44
+ element="select"
45
+ class="no-flex"
46
+ v-model="radius"
47
+ :show-label="cmdFormElementRadius.showLabel"
48
+ :labelText="cmdFormElementRadius.labelText"
49
+ :select-options="cmdFormElementRadius.selectOptions"
50
+ />
51
+ <!-- end CmdFormElement for radius -->
52
+ </div>
53
+
54
+ <!-- begin CmdFormElement for search-button -->
35
55
  <CmdFormElement
36
56
  element="button"
37
- :buttonText="buttonText"
38
- :buttonIcon="{iconClass: 'icon-search', iconPosition: 'before'}"
39
- @click="$emit('click', $event)"
57
+ :nativeButton="cmdFormElementSearchButton"
58
+ @click="onSearchButtonClick"
40
59
  aria-live="assertive"
41
60
  />
42
- <!-- end CmdFormElement -->
61
+ <!-- end CmdFormElement for search-button -->
62
+
43
63
  </div>
44
64
  <!-- end form-elements -->
45
65
 
46
66
  <!-- begin filters -->
47
- <template v-if="useFilters">
67
+ <template v-if="cmdFakeSelect?.show">
48
68
  <a href="#" @click.prevent="showFilters = !showFilters">
49
69
  <span :class="showFilters ? 'icon-single-arrow-up' : 'icon-single-arrow-down'"></span>
50
70
  <span v-if="showFilters">{{ getMessage("cmdsitesearch.hide_filter_options") }}</span>
51
71
  <span v-else>{{ getMessage("cmdsitesearch.show_filter_options") }}</span>
52
72
  </a>
53
73
  <transition name="fade">
54
- <div v-if="showFilters && listOfFilters.length" class="flex-container no-flex" aria-expanded="true">
74
+ <div v-if="showFilters && cmdFakeSelect?.selectData.length" class="flex-container no-flex" aria-expanded="true">
55
75
  <!-- begin CmdFakeSelect -->
56
76
  <CmdFakeSelect
57
- :selectData="listOfFilters"
58
- v-model="fakeSelectFilters"
59
- defaultOptionName="Select filters:"
60
- type="checkboxOptions"
61
- labelText="Filters:"
77
+ :selectData="cmdFakeSelect?.selectData"
78
+ v-model="searchFilters"
79
+ :defaultOptionName="cmdFakeSelect?.defaultOptionName"
80
+ :type="cmdFakeSelect?.type"
81
+ :labelText="cmdFakeSelect?.labelText"
62
82
  />
63
83
  <!-- end CmdFakeSelect -->
64
84
  </div>
@@ -66,7 +86,7 @@
66
86
  </template>
67
87
  <!-- end filters -->
68
88
  </fieldset>
69
- <CmdFormFilters v-if="useFilters" v-model="fakeSelectFilters" :selectedOptionsName="getOptionName"/>
89
+ <CmdFormFilters v-if="cmdFakeSelect?.show" v-model="searchFilters" :selectedOptionsName="getOptionName"/>
70
90
  </template>
71
91
 
72
92
  <script>
@@ -81,6 +101,13 @@ import CmdFormElement from "./CmdFormElement"
81
101
  import CmdFormFilters from "./CmdFormFilters"
82
102
 
83
103
  export default {
104
+ emits: [
105
+ "search",
106
+ "update:modelValueInput1",
107
+ "update:modelValueInput2",
108
+ "update:modelValueRadius",
109
+ "update:modelValueSearchFilters"
110
+ ],
84
111
  name: "CmdBoxSiteSearch",
85
112
  mixins: [I18n, DefaultMessageProperties],
86
113
  components: {
@@ -91,34 +118,45 @@ export default {
91
118
  },
92
119
  data() {
93
120
  return {
94
- showFilters: false,
95
- fakeSelectFilters: []
121
+ showFilters: false
96
122
  }
97
123
  },
98
124
  props: {
99
125
  /**
100
- * the native modelValue for v-model given from outside for pre-sets
126
+ * custom modelValue for first input-field
101
127
  */
102
- modelValue: {
103
- type: Array,
128
+ modelValueInput1: {
129
+ type: String,
104
130
  required: false
105
131
  },
106
132
  /**
107
- * toggle use of filters (must configured)
133
+ * custom modelValue for second input-field
108
134
  */
109
- useFilters: {
110
- type: Boolean,
111
- default: true
135
+ modelValueInput2: {
136
+ type: String,
137
+ required: false
112
138
  },
113
139
  /**
114
- * set list of filters
115
- *
116
- * useFilters-property must be activated
140
+ * custom modelValue for radius
141
+ */
142
+ modelValueRadius: {
143
+ type: [String, Number],
144
+ required: false
145
+ },
146
+ /**
147
+ * custom modelValue for search-filters
117
148
  */
118
- listOfFilters: {
149
+ modelValueSearchFilters: {
119
150
  type: Array,
120
151
  required: false
121
152
  },
153
+ /**
154
+ * toggle use of filters (must configured)
155
+ */
156
+ useFilters: {
157
+ type: Boolean,
158
+ default: true
159
+ },
122
160
  /**
123
161
  * text for legend
124
162
  *
@@ -150,31 +188,168 @@ export default {
150
188
  cmdCustomHeadline: {
151
189
  type: Object,
152
190
  required: false
191
+ },
192
+ /**
193
+ * properties for CmdFormElement-component first search-field
194
+ */
195
+ cmdFormElementInput1: {
196
+ type: Object,
197
+ default() {
198
+ return {
199
+ show: true,
200
+ type: "text",
201
+ showLabel: true,
202
+ labelText: "What do you like to search for?",
203
+ placeholder: "Search"
204
+ }
205
+ }
206
+ },
207
+ /**
208
+ * properties for CmdFormElement-component for second search-field
209
+ */
210
+ cmdFormElementInput2: {
211
+ type: Object,
212
+ default() {
213
+ return {
214
+ show: true,
215
+ type: "text",
216
+ showLabel: true,
217
+ labelText: "Where do you like to search?",
218
+ placeholder: "City, Zip"
219
+ }
220
+ }
221
+ },
222
+ /**
223
+ * properties for CmdFormElement-component for radius
224
+ */
225
+ cmdFormElementRadius: {
226
+ type: Object,
227
+ default() {
228
+ return {
229
+ show: true,
230
+ showLabel: true,
231
+ labelText: "Radius",
232
+ selectOptions: [
233
+ {
234
+ text: "5 Km",
235
+ value: 5
236
+ },
237
+ {
238
+ text: "10 Km",
239
+ value: 10
240
+ },
241
+ {
242
+ text: "15 Km",
243
+ value: 15
244
+ },
245
+ {
246
+ text: "50 Km",
247
+ value: 50
248
+ },
249
+ {
250
+ text: "100 Km",
251
+ value: 100
252
+ }
253
+ ]
254
+ }
255
+ }
256
+ },
257
+ /**
258
+ * properties for CmdFormElement-component for search-button
259
+ */
260
+ cmdFormElementSearchButton: {
261
+ type: Object,
262
+ default() {
263
+ return {
264
+ icon: {
265
+ show: true,
266
+ position: "before",
267
+ iconClass: "icon-search"
268
+ },
269
+ text: "Search"
270
+ }
271
+ }
272
+ },
273
+ /**
274
+ * properties for CmdFakeSelect-component for filters
275
+ */
276
+ cmdFakeSelect: {
277
+ type: Object,
278
+ required: false
153
279
  }
154
280
  },
155
281
  computed: {
156
- buttonText() {
157
- if (this.results) {
158
- return this.results + " Results"
282
+ searchValue1: {
283
+ get() {
284
+ return this.modelValueInput1
285
+ },
286
+ set(value) {
287
+ this.$emit("update:modelValueInput1", value)
288
+ }
289
+ },
290
+ searchValue2: {
291
+ get() {
292
+ return this.modelValueInput2
293
+ },
294
+ set(value) {
295
+ this.$emit("update:modelValueInput2", value)
296
+ }
297
+ },
298
+ radius: {
299
+ get() {
300
+ return this.modelValueRadius
301
+ },
302
+ set(value) {
303
+ this.$emit("update:modelValueRadius", value)
304
+ }
305
+ },
306
+ searchFilters: {
307
+ get() {
308
+ return this.modelValueSearchFilters
309
+ },
310
+ set(value) {
311
+ this.$emit("update:modelValueSearchFilters", value)
159
312
  }
160
- return "Search"
161
313
  }
162
314
  },
163
315
  methods: {
316
+ onSearchButtonClick() {
317
+ this.$emit("search", {
318
+ searchValue1: this.searchValue1,
319
+ searchValue2: this.searchValue2,
320
+ searchFilters: this.searchFilters,
321
+ radius: this.radius
322
+ })
323
+ },
164
324
  getOptionName(option) {
165
- for (let i = 0; i < this.listOfFilters.length; i++) {
166
- if (option === this.listOfFilters[i].value) {
167
- return this.listOfFilters[i].text
325
+ for (let i = 0; i < this.cmdFakeSelect.selectData.length; i++) {
326
+ if (option === this.cmdFakeSelect.selectData[i].value) {
327
+ return this.cmdFakeSelect.selectData[i].text
168
328
  }
169
329
  }
170
330
  return null
171
331
  }
332
+ },
333
+ watch: {
334
+ cmdFormElementRadius: {
335
+ handler() {
336
+ if (this.cmdFormElementRadius?.selectOptions && this.cmdFormElementRadius?.selectOptions.length && this.modelValueRadius == null) {
337
+ this.radius = this.cmdFormElementRadius.selectOptions[0].value
338
+ }
339
+ },
340
+ immediate: true,
341
+ deep: true
342
+ }
172
343
  }
173
344
  }
174
345
  </script>
175
346
 
176
347
  <style lang="scss">
348
+ /* begin cmd-box-site-search ---------------------------------------------------------------------------------------- */
349
+ @import '../assets/styles/variables';
177
350
  .cmd-box-site-search {
351
+ flex-wrap: nowrap;
352
+
178
353
  > a {
179
354
  [class*='icon'] {
180
355
  font-size: 1rem;
@@ -185,4 +360,11 @@ export default {
185
360
  align-self: flex-end;
186
361
  }
187
362
  }
363
+
364
+ @media only screen and (max-width: $small-max-width) {
365
+ .cmd-box-site-search {
366
+ flex-wrap: nowrap;
367
+ }
368
+ }
369
+ /* end cmd-box-site-search ---------------------------------------------------------------------------------------- */
188
370
  </style>
@@ -1,10 +1,10 @@
1
1
  <template>
2
2
  <div class="cmd-company-logo">
3
- <router-link v-if="link.type === 'router'" :href="link.path" :title="link.tooltip">
3
+ <router-link v-if="link.type === 'router'" :to="link.path" :title="link.tooltip">
4
4
  <img :src="pathCurrentLogo" :alt="altText"/>
5
5
  </router-link>
6
- <a v-else :to="link.path" :title="link.tooltip">
7
- <img :src="pathCurrentLogo" :alt="altText"/>
6
+ <a v-else :href="link.path" :title="link.tooltip">
7
+ <img :src="pathCurrentLogo" :alt="altText" />
8
8
  </a>
9
9
  </div>
10
10
  </template>
@@ -53,26 +53,51 @@ export default {
53
53
  },
54
54
  computed: {
55
55
  pathCurrentLogo() {
56
- if (this.prefersColorScheme === 'light' || !this.pathDarkmodeLogo) {
56
+ if (this.prefersColorScheme === "light" || !this.pathDarkmodeLogo) {
57
57
  return this.pathDefaultLogo
58
58
  }
59
59
  return this.pathDarkmodeLogo
60
60
  }
61
61
  },
62
62
  created() {
63
- if (matchMedia('(prefers-color-scheme: light)').matches) {
64
- this.prefersColorScheme = "light"
65
- } else {
66
- this.prefersColorScheme = "dark"
67
- }
63
+ this.toggleColorScheme()
64
+
65
+ window.matchMedia("(prefers-color-scheme: light)").addEventListener("change", this.onColorSchemeChange)
68
66
 
69
- window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', e => {
70
- this.prefersColorScheme = e.matches ? "light" : "dark"
71
- });
67
+ /* observe if class changes in html-tag */
68
+ const htmlTag = document.querySelector("html")
69
+ this.$_observer = new MutationObserver(this.observeDom)
70
+ this.$_observer.observe(htmlTag, {attributes: true})
71
+ },
72
+ beforeUnmount() {
73
+ window.matchMedia("(prefers-color-scheme: light)").removeEventListener("change", this.onColorSchemeChange)
74
+ this.$_observer.disconnect()
72
75
  },
73
76
  methods: {
77
+ onColorSchemeChange(event) {
78
+ this.prefersColorScheme = event.matches ? "light" : "dark"
79
+ },
80
+ observeDom(mutationList) {
81
+ for(let i = 0; i < mutationList.length; i++) {
82
+ if(mutationList[i].type === 'attributes') {
83
+ this.toggleColorScheme()
84
+ break
85
+ }
86
+ }
87
+ },
74
88
  getRoute(language) {
75
89
  return getRoute(language)
90
+ },
91
+ toggleColorScheme() {
92
+ if (document.querySelector("html").classList.contains("light-mode")) {
93
+ this.prefersColorScheme = "light"
94
+ } else if(document.querySelector("html").classList.contains("dark-mode")) {
95
+ this.prefersColorScheme = "dark"
96
+ } else if (matchMedia("(prefers-color-scheme: light)").matches) {
97
+ this.prefersColorScheme = "light"
98
+ } else {
99
+ this.prefersColorScheme = "dark"
100
+ }
76
101
  }
77
102
  }
78
103
  }