comand-component-library 3.1.67 → 3.1.70

Sign up to get free protection for your applications and to get access to all the features.
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 {