comand-component-library 3.1.67 → 3.1.70

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 (31) 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 +214 -146
  5. package/src/assets/fonts/iconfonts/logos-iconfont/icomoon.woff +0 -0
  6. package/src/assets/fonts/iconfonts/logos-iconfont/selection.json +1 -0
  7. package/src/assets/styles/global-styles.scss +30 -48
  8. package/src/assets/styles/logos-iconfont.css +47 -32
  9. package/src/components/CmdBackToTopButton.vue +1 -1
  10. package/src/components/CmdBox.vue +47 -25
  11. package/src/components/CmdBoxSiteSearch.vue +228 -46
  12. package/src/components/CmdCompanyLogo.vue +34 -9
  13. package/src/components/CmdCookieDisclaimer.vue +0 -17
  14. package/src/components/CmdCustomHeadline.vue +1 -1
  15. package/src/components/CmdFakeSelect.vue +19 -19
  16. package/src/components/CmdFormElement.vue +135 -112
  17. package/src/components/CmdInputGroup.vue +120 -4
  18. package/src/components/CmdListOfLinks.vue +6 -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/CmdSiteHeader.vue +13 -4
  23. package/src/components/CmdTabs.vue +3 -7
  24. package/src/components/CmdThumbnailScroller.vue +1 -1
  25. package/src/components/CmdToggleDarkMode.vue +66 -0
  26. package/src/components/CmdUploadForm.vue +5 -6
  27. package/src/index.js +0 -1
  28. package/src/mixins/FieldValidation.js +1 -1
  29. package/src/utils/{GetFileExtension.js → getFileExtension.js} +0 -0
  30. package/src/assets/fonts/iconfonts/logos-iconfont/logos-iconfont.json +0 -1
  31. package/src/components/CmdSwitchButton.vue +0 -181
@@ -3,65 +3,57 @@
3
3
  :class="[
4
4
  'cmd-form-element',
5
5
  validationStatus,
6
- {
7
- disabled: $attrs.disabled,
8
- inline : displayLabelInline,
9
- checked: isChecked,
10
- 'toggle-switch-label': toggleSwitch,
11
- colored: colored,
12
- on: colored && isChecked,
13
- off: colored && !isChecked,
14
- 'has-state': validationStatus
15
- }]"
6
+ $attrs.class,
7
+ {
8
+ disabled: $attrs.disabled,
9
+ inline : displayLabelInline,
10
+ checked: isChecked,
11
+ 'toggle-switch': toggleSwitch,
12
+ colored: colored,
13
+ on: colored && isChecked,
14
+ off: colored && !isChecked,
15
+ 'has-state': validationStatus
16
+ }]"
16
17
  :for="labelId"
17
18
  ref="label">
18
19
 
19
20
  <!-- begin label-text (+ required asterisk) -->
20
21
  <span v-if="labelText && $attrs.type !== 'checkbox' && $attrs.type !== 'radio'"
21
- :class="!showLabel ? 'hidden' : undefined">
22
- <span>
23
- {{ labelText }}<sup v-if="$attrs.required">*</sup>
24
- </span>
25
- <a v-if="$attrs.required || inputRequirements.length"
26
- href="#"
27
- @click.prevent
28
- :class="getStatusIconClass"
29
- :title="validationTooltip"
30
- :aria-errormessage="getValidationMessage"
31
- aria-live="assertive"
32
- :id="tooltipId"
33
- :role="validationStatus === 'error' ? 'alert' : 'dialog'">
34
- </a>
35
- </span>
22
+ :class="['label-text', !showLabel ? 'hidden' : undefined]">
23
+ <span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
24
+ <a v-if="$attrs.required || inputRequirements.length"
25
+ href="#"
26
+ @click.prevent
27
+ :class="getStatusIconClass"
28
+ :title="validationTooltip"
29
+ :aria-errormessage="getValidationMessage"
30
+ aria-live="assertive"
31
+ :id="tooltipId"
32
+ :role="validationStatus === 'error' ? 'alert' : 'dialog'">
33
+ </a>
34
+ </span>
36
35
  <!-- end label-text (+ required asterisk) -->
37
36
 
38
- <!-- begin icon -->
39
- <span
40
- v-if="
41
- $attrs.type !== 'checkbox' &&
42
- $attrs.type !== 'radio' &&
43
- fieldIconClass
44
- "
45
- :class="['place-inside', fieldIconClass]"
46
- ></span>
47
- <!-- end icon -->
37
+ <!-- begin icon inside field -->
38
+ <span v-if="$attrs.type !== 'checkbox' && $attrs.type !== 'radio' && fieldIconClass" :class="['place-inside', fieldIconClass]"></span>
39
+ <!-- end icon inside field -->
48
40
 
49
41
  <!-- begin inputfield -->
50
- <template
51
- v-if="element === 'input' && $attrs.type !== 'checkbox' && $attrs.type !== 'radio' && $attrs.type !== 'search'">
52
- <input v-bind="$attrs"
53
- :id="labelId"
54
- :class="htmlClass"
55
- @focus="tooltip = true"
56
- @blur="onBlur"
57
- @input="onInput"
58
- @mouseover="datalistFocus"
59
- @keyup="checkForCapsLock"
60
- :autocomplete="autocomplete"
61
- :list="datalist ? datalist.id : null"
62
- :value="modelValue"
63
- :maxlength="getMaxLength()"
64
- ref="input"
42
+ <template v-if="element === 'input' && $attrs.type !== 'checkbox' && $attrs.type !== 'radio' && $attrs.type !== 'search'">
43
+ <input
44
+ v-bind="elementAttributes"
45
+ :id="labelId"
46
+ :class="inputClass"
47
+ @focus="tooltip = true"
48
+ @blur="onBlur"
49
+ @input="onInput"
50
+ @mouseover="datalistFocus"
51
+ @keyup="checkForCapsLock"
52
+ :autocomplete="autocomplete"
53
+ :list="datalist ? datalist.id : null"
54
+ :value="modelValue"
55
+ :maxlength="getMaxLength()"
56
+ ref="input"
65
57
  />
66
58
  </template>
67
59
  <!-- end inputfield -->
@@ -88,37 +80,46 @@
88
80
 
89
81
  <!-- begin checkbox and radiobutton -->
90
82
  <template v-else-if="element === 'input' && ($attrs.type === 'checkbox' || $attrs.type === 'radio')">
91
- <input v-bind="$attrs"
92
- @change="onChange"
93
- @blur="onBlur"
94
- :checked="isChecked"
95
- :value="inputValue"
96
- :class="[htmlClass, validationStatus, { 'replace-input-type': replaceInputType, 'toggle-switch': toggleSwitch }]"
97
- :id="labelId"
98
- :aria-invalid="validationStatus === 'error'"
99
- />
100
- <span v-if="!(onLabel && offLabel)" :class="{ hidden: !showLabel }">
101
- <span v-if="labelText">{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
102
- </span>
103
-
104
- <!-- begin labels for toggle-switch -->
83
+ <template v-if="!(onLabel && offLabel)">
84
+ <input
85
+ v-bind="elementAttributes"
86
+ @change="onChange"
87
+ @blur="onBlur"
88
+ :checked="isChecked"
89
+ :value="inputValue"
90
+ :class="[inputClass, validationStatus, toggleSwitchIconClass, { 'replace-input-type': replaceInputType, 'toggle-switch': toggleSwitch }]"
91
+ :id="labelId"
92
+ :aria-invalid="validationStatus === 'error'"
93
+ />
94
+ <span v-if="labelText" :class="['label-text', { hidden: !showLabel }]"><span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span></span>
95
+ </template>
96
+ <!-- begin labels for toggle-switch with switch-label -->
105
97
  <template v-else-if="onLabel && offLabel">
106
- <span v-if="labelText">
107
- <span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
98
+ <span class="switch-label-wrapper">
99
+ <input v-bind="elementAttributes"
100
+ @change="onChange"
101
+ @blur="onBlur"
102
+ :checked="isChecked"
103
+ :value="inputValue"
104
+ :class="{inputClass, validationStatus}"
105
+ :id="labelId"
106
+ :aria-invalid="validationStatus === 'error'"
107
+ />
108
+ <span class="label-text">{{ onLabel }}</span>
109
+ <span class="label-text">{{ offLabel }}</span>
108
110
  </span>
109
- <span class="toggle-switch switch-label">
110
- <span class="label">{{ onLabel }}</span>
111
- <span class="label">{{ offLabel }}</span>
111
+ <span v-if="labelText" class="label-text">
112
+ <span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
112
113
  </span>
113
114
  </template>
114
115
  <slot v-else></slot>
115
- <!-- end labels for toggle-switch -->
116
+ <!-- end labels for toggle-switch with switch-label -->
116
117
  </template>
117
118
  <!-- end checkbox and radiobutton -->
118
119
 
119
120
  <!-- begin selectbox -->
120
121
  <select v-if="element === 'select'"
121
- v-bind="$attrs"
122
+ v-bind="elementAttributes"
122
123
  :id="labelId"
123
124
  @blur="onBlur"
124
125
  @change="$emit('update:modelValue', $event.target.value)">
@@ -130,7 +131,7 @@
130
131
 
131
132
  <!-- begin textarea -->
132
133
  <textarea v-if="element === 'textarea'"
133
- v-bind="$attrs"
134
+ v-bind="elementAttributes"
134
135
  :id="labelId"
135
136
  :value="modelValue"
136
137
  :maxlength="getMaxLength()"
@@ -144,18 +145,18 @@
144
145
  <!-- begin searchfield -->
145
146
  <template v-else-if="element === 'input' && $attrs.type === 'search'">
146
147
  <div class="search-field-wrapper flex-container no-gap">
147
- <a v-if="iconDelete.show" href="#" @click.prevent="$emit('update:modelValue', '')" :class="iconDelete.iconClass" :title="iconDelete.tooltip"/>
148
148
  <input
149
- v-bind="$attrs"
149
+ v-bind="elementAttributes"
150
150
  :id="labelId"
151
151
  @input="onInput"
152
152
  :maxlength="$attrs.maxlength > 0 ? $attrs.maxlength : 255"
153
153
  :value="modelValue"
154
154
  />
155
+ <a v-if="showSearchButton" href="#" class="button no-flex" :title="iconSearch.tooltip" @click.prevent="executeSearch">
156
+ <span :class="iconSearch.iconClass"></span>
157
+ </a>
158
+ <a v-if="iconDelete.show" href="#" @click.prevent="$emit('update:modelValue', '')" :class="iconDelete.iconClass" :title="iconDelete.tooltip"></a>
155
159
  </div>
156
- <a v-if="showSearchButton" href="#" class="button no-flex" :title="iconSearch.tooltip" @click.prevent="executeSearch">
157
- <span :class="iconSearch.iconClass"></span>
158
- </a>
159
160
  </template>
160
161
  </label>
161
162
  <!-- end searchfield -->
@@ -332,7 +333,7 @@ export default {
332
333
  * allow checkbox/radio-buttons to get value from outside
333
334
  */
334
335
  inputValue: {
335
- type: String,
336
+ type: [String, Number],
336
337
  required: false
337
338
  },
338
339
  /**
@@ -349,7 +350,7 @@ export default {
349
350
  *
350
351
  * may not be named as 'class' because it is a reserved keyword in JavaScript
351
352
  */
352
- htmlClass: {
353
+ inputClass: {
353
354
  type: String,
354
355
  required: false
355
356
  },
@@ -547,6 +548,14 @@ export default {
547
548
  }
548
549
  }
549
550
  },
551
+ toggleSwitchUncheckedIconClass: {
552
+ type: String,
553
+ default: "icon-cancel-circle"
554
+ },
555
+ toggleSwitchCheckedIconClass: {
556
+ type: String,
557
+ default: "icon-check-circle"
558
+ },
550
559
  /**
551
560
  * icon to toggle password-visibility
552
561
  *
@@ -582,6 +591,19 @@ export default {
582
591
  },
583
592
  },
584
593
  computed: {
594
+ elementAttributes() {
595
+ const commonAttributes = ["name", "required", "readonly", "disabled", "autofocus"]
596
+ const attributes = {
597
+ input: [...commonAttributes, "type", "minlength", "pattern", "min", "max", "multiple", "step", "autocomplete", "placeholder"],
598
+ select: [...commonAttributes, "multiple"],
599
+ textarea: [...commonAttributes, "placeholder"]
600
+ }
601
+ const attrs = {}
602
+ if (attributes[this.element]) {
603
+ Object.entries(this.$attrs).filter(([name]) => attributes[this.element].includes(name)).forEach(([name, value]) => attrs[name] = value)
604
+ }
605
+ return attrs
606
+ },
585
607
  buttonAttrs() {
586
608
  // copy all native attributes
587
609
  const allAttrs = {...this.$attrs}
@@ -600,6 +622,8 @@ export default {
600
622
  }
601
623
  },
602
624
  isChecked() {
625
+ console.log("this.modelValue", this.modelValue)
626
+ console.log("typeof this.modelValue", typeof this.modelValue)
603
627
  if (typeof this.modelValue === "boolean") {
604
628
  return this.modelValue
605
629
  }
@@ -633,17 +657,26 @@ export default {
633
657
  return this.getMessage("cmdformelement.validationTooltip.open_field_requirements")
634
658
  },
635
659
  autocomplete() {
636
- if(this.$attrs.type !== 'file') {
660
+ if (this.$attrs.type !== 'file') {
637
661
  return this.datalist ? 'off' : 'on'
638
662
  }
639
663
  return null
640
664
  },
641
665
  // get ID for accessibility
642
666
  labelId() {
643
- if(this.$attrs.id !== undefined) {
667
+ if (this.$attrs.id !== undefined) {
644
668
  return this.$attrs.id
645
669
  }
646
670
  return "label-" + createUuid()
671
+ },
672
+ toggleSwitchIconClass() {
673
+ if(this.toggleSwitch && this.toggleSwitchUncheckedIconClass && this.toggleSwitchCheckedIconClass) {
674
+ if(this.isChecked) {
675
+ return this.toggleSwitchCheckedIconClass
676
+ }
677
+ return this.toggleSwitchUncheckedIconClass
678
+ }
679
+ return null
647
680
  }
648
681
  },
649
682
  methods: {
@@ -656,7 +689,7 @@ export default {
656
689
  }
657
690
 
658
691
  if (this.$attrs.type !== 'file') {
659
- return this.$attrs.maxlength > 0 ? this.$attrs.maxlength : 255
692
+ return this.$attrs.maxlength > 0 ? this.$attrs.maxlength : 255
660
693
  }
661
694
 
662
695
  return null
@@ -750,6 +783,12 @@ export default {
750
783
 
751
784
  <style lang="scss">
752
785
  .cmd-form-element {
786
+
787
+
788
+
789
+
790
+
791
+
753
792
  input + .place-inside[class*="icon"] {
754
793
  left: auto;
755
794
  right: .5rem
@@ -800,15 +839,17 @@ export default {
800
839
  .search-field-wrapper {
801
840
  margin: 0;
802
841
 
803
- a {
842
+ a[class*="icon"] {
804
843
  position: absolute;
805
844
  top: 50%;
806
845
  right: 1rem;
807
846
  transform: translateY(-50%);
808
847
  z-index: 100;
848
+ }
809
849
 
810
- & + input {
811
- padding-right: calc(var(--default-padding) * 3);
850
+ a.button {
851
+ & + a[class*="icon"] {
852
+ right: 5rem;
812
853
  }
813
854
  }
814
855
  }
@@ -816,7 +857,6 @@ export default {
816
857
  .place-inside {
817
858
  + .search-field-wrapper {
818
859
 
819
-
820
860
  input {
821
861
  padding-left: calc(var(--default-padding) * 3);
822
862
  }
@@ -824,33 +864,15 @@ export default {
824
864
  }
825
865
 
826
866
  /* begin toggle-switch */
827
- /* no cmd-prefix-styling (class based on frontend-framework */
867
+ /* no cmd-prefix-styling (class based on frontend-framework) */
828
868
  &.toggle-switch {
829
- &.switch-label {
830
- input {
831
- & + .label {
832
- padding-right: calc(var(--default-padding) / 3 * 2);
833
-
834
- &::before {
835
- top: 0.2rem;
836
- }
837
-
838
- & + .label {
839
- padding-left: calc(var(--default-padding) / 3 * 2);
840
-
841
- &::before {
842
- top: 0.2rem;
843
- }
844
- }
845
- }
846
- }
847
-
848
- &.colored {
849
- &.off {
869
+ &.colored {
870
+ &.off {
871
+ .switch-label-wrapper {
850
872
  border-color: var(--error-color);
851
873
 
852
874
  span {
853
- &.label {
875
+ &.label-text {
854
876
  color: var(--error-color);
855
877
 
856
878
  &::before {
@@ -860,12 +882,14 @@ export default {
860
882
  }
861
883
  }
862
884
  }
885
+ }
863
886
 
864
- &.on {
887
+ &.on {
888
+ .switch-label-wrapper {
865
889
  border-color: var(--success-color);
866
890
 
867
891
  span {
868
- &.label {
892
+ &.label-text {
869
893
  color: var(--success-color);
870
894
 
871
895
  &::before {
@@ -878,7 +902,6 @@ export default {
878
902
  }
879
903
  }
880
904
  }
881
-
882
905
  /* end toggle-switch ------------------------------------------------------------------------------------------ */
883
906
  }
884
907
  </style>
@@ -1,15 +1,79 @@
1
1
  <template>
2
- <div class="cmd-input-group">
3
- <span :class="['label', { hidden: !showLabel, inline: labelInline }]">{{ labelText }}</span>
4
- <div class="flex-container no-flex">
2
+ <div :class="['cmd-input-group', {inline: labelInline, 'multiple-switch': multipleSwitch}]">
3
+ <span :class="['label', { hidden: !showLabel}]" :id="labelId" :aria-labelledby="labelId">{{ labelText }}</span>
4
+ <span v-if="!useSlot" :class="['flex-container', {'no-flex': !stretchHorizontally, 'no-gap': multipleSwitch}]">
5
+ <label v-for="(inputElement, index) in inputElements" :key="index" :for="inputElement.id">
6
+ <input :type="inputTypes"
7
+ :id="inputElement.id"
8
+ :name="inputElement.name"
9
+ :value="inputElement.value"
10
+ v-model="inputValue"
11
+ />
12
+ <span v-if="multipleSwitch && inputElement.iconClass" :class="inputElement.iconClass"></span>
13
+ <span v-if="inputElement.labelText">{{ inputElement.labelText }}</span>
14
+ </label>
15
+ </span>
16
+ <!-- begin useSlot -->
17
+ <div v-else class="flex-container no-flex">
18
+ <!-- begin slot -->
5
19
  <slot></slot>
20
+ <!-- end slot -->
6
21
  </div>
22
+ <!-- end useSlot -->
7
23
  </div>
8
24
  </template>
9
25
 
10
26
  <script>
27
+ import {createUuid} from "../utils/common"
28
+
11
29
  export default {
30
+ data() {
31
+ return {
32
+ value: ""
33
+ }
34
+ },
12
35
  props: {
36
+ /**
37
+ * set value for v-model (must be named modelValue in vue3 if default v-model should be used)
38
+ */
39
+ modelValue: {
40
+ type: [Array, String],
41
+ required: false
42
+ },
43
+ /**
44
+ * list of input-elements inside group
45
+ *
46
+ * useSlot-property must be set to 'false'
47
+ */
48
+ inputElements: {
49
+ type: Array,
50
+ required: false
51
+ },
52
+ /**
53
+ * set type for inputs in group
54
+ *
55
+ * @allowedValues: checkbox, radio
56
+ */
57
+ inputTypes: {
58
+ type: String,
59
+ default: "radio"
60
+ },
61
+ /**
62
+ * activate if input-elements should be given by slot
63
+ */
64
+ useSlot: {
65
+ type: Boolean,
66
+ default: false
67
+ },
68
+ /**
69
+ * toggle multipleSwitch-styling
70
+ *
71
+ * @affectsStyling: true
72
+ */
73
+ multipleSwitch: {
74
+ type: Boolean,
75
+ default: false
76
+ },
13
77
  /**
14
78
  * toggle label-text visibility
15
79
  */
@@ -32,7 +96,59 @@ export default {
32
96
  labelInline: {
33
97
  type: Boolean,
34
98
  default: false
99
+ },
100
+ /**
101
+ * toggle if input-elements will be stretched horizontally
102
+ *
103
+ * @affectsStyling: true
104
+ */
105
+ stretchHorizontally: {
106
+ type: Boolean,
107
+ default: false
108
+ }
109
+ },
110
+ computed: {
111
+ // get ID for accessibility
112
+ labelId() {
113
+ if(this.$attrs.id !== undefined) {
114
+ return this.$attrs.id
115
+ }
116
+ return "label-" + createUuid()
117
+ },
118
+ inputValue: {
119
+ // read inputValue
120
+ get() {
121
+ return this.modelValue
122
+ },
123
+ // set/write a value to update v-model for this component
124
+ set(value) {
125
+ this.$emit("update:modelValue", value)
126
+ }
35
127
  }
128
+ },
129
+ methods: {
130
+ onChange(e) {
131
+ if (typeof this.value === "string") {
132
+ this.$emit("update:value", e.target.value)
133
+ } else if (this.value !== undefined) {
134
+ let values = [...this.value]
135
+ if (e.target.checked) {
136
+ values.push(e.target.value)
137
+ } else {
138
+ values = values.filter(value => value !== e.target.value)
139
+ }
140
+ this.$emit("update:modelValue", values)
141
+ }
142
+ }
143
+ }
144
+ }
145
+ </script>
146
+
147
+ <style lang="scss">
148
+ .cmd-input-group {
149
+ &.inline {
150
+ display: flex;
151
+ gap: var(--default-gap);
36
152
  }
37
153
  }
38
- </script>
154
+ </style>
@@ -137,6 +137,7 @@ export default {
137
137
  ul {
138
138
  flex-direction: column;
139
139
  gap: calc(var(--default-gap) / 2);
140
+ margin: 0;
140
141
 
141
142
  li {
142
143
  list-style: none;
@@ -145,23 +146,24 @@ export default {
145
146
  }
146
147
 
147
148
  &.horizontal {
149
+ flex-direction: row;
150
+
148
151
  ul {
149
- flex-direction: row;
150
152
  gap: var(--default-gap);
153
+ flex-direction: row;
151
154
 
152
155
  > li {
153
156
  flex: none;
154
157
  display: flex;
155
- align-items: center;
156
158
  }
157
159
  }
158
160
 
159
161
  &.align-center {
160
- align-items: center;
162
+ justify-content: center;
161
163
  }
162
164
 
163
165
  &.align-right {
164
- align-items: flex-end;
166
+ justify-content: flex-end;
165
167
  }
166
168
  }
167
169
  }
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <!-- begin login-form -->
3
- <fieldset v-if="!sendLogin" class="flex-container">
3
+ <fieldset v-if="!sendLogin" class="cmd-login-form flex-container">
4
4
  <legend :class="{hidden : !showLegend}">{{ textLegend }}</legend>
5
5
  <!-- begin CmdCustomHeadline -->
6
6
  <CmdCustomHeadline v-if="cmdCustomHeadlineLoginForm"
@@ -119,7 +119,7 @@
119
119
  <!-- end login-form -->
120
120
 
121
121
  <!-- begin send-login-form -->
122
- <fieldset v-else class="flex-container">
122
+ <fieldset v-else class="cmd-login-form flex-container">
123
123
  <legend :class="{'hidden' : !legendSendLoginForm.show}">{{ legendSendLoginForm.text }}</legend>
124
124
  <!-- begin CmdCustomHeadline -->
125
125
  <CmdCustomHeadline v-if="cmdCustomHeadlineSendLoginForm"
@@ -439,6 +439,7 @@ export default {
439
439
  </script>
440
440
 
441
441
  <style lang="scss">
442
+ .cmd-login-form {
442
443
  .option-wrapper {
443
444
  align-items: center;
444
445
 
@@ -458,4 +459,5 @@ export default {
458
459
  margin-left: auto;
459
460
  }
460
461
  }
462
+ }
461
463
  </style>
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <div :class="['label', 'multiple-switch', {disabled: status === 'disabled', error: status === 'error'}]">
3
- <span :class="{hidden: !showLabel}">{{ labelText }}</span>
2
+ <div :class="['cmd-multiple-switch multiple-switch label', {disabled: status === 'disabled', error: status === 'error'}]" :aria-labelledby="labelId">
3
+ <span :class="{hidden: !showLabel}" :id="labelId">{{ labelText }}</span>
4
4
  <span class="flex-container no-gap no-flex">
5
5
  <label :class="{disabled: status === 'disabled'}" :for="multipleswitch.id"
6
6
  v-for="(multipleswitch, index) in multipleSwitches" :key="index">
@@ -20,6 +20,9 @@
20
20
  </template>
21
21
 
22
22
  <script>
23
+ // import utils
24
+ import {createUuid} from "../utils/common.js"
25
+
23
26
  export default {
24
27
  name: "CmdMultipleSwitch",
25
28
  props: {
@@ -80,6 +83,15 @@ export default {
80
83
  required: false
81
84
  }
82
85
  },
86
+ computed: {
87
+ // get ID for accessibility
88
+ labelId() {
89
+ if(this.$attrs.id !== undefined) {
90
+ return this.$attrs.id
91
+ }
92
+ return "label-" + createUuid()
93
+ }
94
+ },
83
95
  methods: {
84
96
  onChange(e) {
85
97
  if (typeof this.value === "string") {
@@ -199,10 +199,10 @@ export default {
199
199
 
200
200
  a {
201
201
  background: none;
202
- color: var(--text-color);
202
+ color: var(--color-scheme-text-color);
203
203
 
204
204
  span, span[class*='color'] {
205
- color: var(--text-color);
205
+ color: inherit;
206
206
 
207
207
  & + span[class*="icon"] {
208
208
  &:last-child {