comand-component-library 3.1.68 → 3.1.69

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,7 +29,7 @@
29
29
  :role="validationStatus === 'error' ? 'alert' : 'dialog'">
30
30
  </a>
31
31
  </span>
32
- <ul :class="{'open': showOptions}" @clickout="closeOptions">
32
+ <ul :class="{'open': showOptions}" @clickout="closeOptions" :aria-expanded="showOptions">
33
33
  <li>
34
34
  <!-- begin default/selected-option -->
35
35
  <a href="#" @click.prevent="toggleOptions" @blur="onBlur">
@@ -42,8 +42,8 @@
42
42
  <!-- end default/selected-option-->
43
43
 
44
44
  <!-- begin default dropdown (incl. optional icon) -->
45
- <ul v-if="type === 'default' && showOptions" :aria-expanded="showOptions">
46
- <li v-for="(option, index) in selectData" :key="index" role="option">
45
+ <ul v-if="type === 'default' && showOptions" role="listbox">
46
+ <li v-for="(option, index) in selectData" :key="index" role="option" :aria-selected="option.value === modelValue">
47
47
  <!-- begin type 'href' -->
48
48
  <a v-if="optionLinkType === 'href'" href="#" @click.prevent="selectOption(option.value)" :class="{'active' : option.value === modelValue}">
49
49
  <span v-if="option.iconClass" :class="option.iconClass"></span>
@@ -475,7 +475,7 @@ export default {
475
475
  margin: 0;
476
476
  display: block;
477
477
  min-width: 0;
478
- background: var(--pure-white);
478
+ background: var(--color-scheme-background-color);
479
479
  box-shadow: none;
480
480
  border-radius: var(--border-radius);
481
481
 
@@ -524,7 +524,7 @@ export default {
524
524
  padding-top: .8rem;
525
525
  outline: none;
526
526
  border-bottom: var(--default-border);
527
- color: var(--text-color);
527
+ color: var(--color-scheme-text-color);
528
528
  text-decoration: none;
529
529
 
530
530
  &:hover, &:active, &:focus {
@@ -3,16 +3,17 @@
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
 
@@ -49,9 +50,9 @@
49
50
  <!-- begin inputfield -->
50
51
  <template
51
52
  v-if="element === 'input' && $attrs.type !== 'checkbox' && $attrs.type !== 'radio' && $attrs.type !== 'search'">
52
- <input v-bind="$attrs"
53
+ <input v-bind="elementAttributes"
53
54
  :id="labelId"
54
- :class="htmlClass"
55
+ :class="inputClass"
55
56
  @focus="tooltip = true"
56
57
  @blur="onBlur"
57
58
  @input="onInput"
@@ -88,37 +89,47 @@
88
89
 
89
90
  <!-- begin checkbox and radiobutton -->
90
91
  <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 }">
92
+ <template v-if="!(onLabel && offLabel)">
93
+ <input v-bind="elementAttributes"
94
+ @change="onChange"
95
+ @blur="onBlur"
96
+ :checked="isChecked"
97
+ :value="inputValue"
98
+ :class="[inputClass, validationStatus, { 'replace-input-type': replaceInputType, 'toggle-switch': toggleSwitch }]"
99
+ :id="labelId"
100
+ :aria-invalid="validationStatus === 'error'"
101
+ />
102
+ <span :class="{ hidden: !showLabel }">
101
103
  <span v-if="labelText">{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
102
104
  </span>
103
-
104
- <!-- begin labels for toggle-switch -->
105
+ </template>
106
+ <!-- begin labels for toggle-switch with switch-label -->
105
107
  <template v-else-if="onLabel && offLabel">
106
- <span v-if="labelText">
107
- <span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
108
- </span>
109
- <span class="toggle-switch switch-label">
108
+ <span class="switch-label-wrapper">
109
+ <input v-bind="elementAttributes"
110
+ @change="onChange"
111
+ @blur="onBlur"
112
+ :checked="isChecked"
113
+ :value="inputValue"
114
+ :class="{inputClass, validationStatus}"
115
+ :id="labelId"
116
+ :aria-invalid="validationStatus === 'error'"
117
+ />
110
118
  <span class="label">{{ onLabel }}</span>
111
119
  <span class="label">{{ offLabel }}</span>
112
120
  </span>
121
+ <span v-if="labelText">
122
+ <span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
123
+ </span>
113
124
  </template>
114
125
  <slot v-else></slot>
115
- <!-- end labels for toggle-switch -->
126
+ <!-- end labels for toggle-switch with switch-label -->
116
127
  </template>
117
128
  <!-- end checkbox and radiobutton -->
118
129
 
119
130
  <!-- begin selectbox -->
120
131
  <select v-if="element === 'select'"
121
- v-bind="$attrs"
132
+ v-bind="elementAttributes"
122
133
  :id="labelId"
123
134
  @blur="onBlur"
124
135
  @change="$emit('update:modelValue', $event.target.value)">
@@ -130,7 +141,7 @@
130
141
 
131
142
  <!-- begin textarea -->
132
143
  <textarea v-if="element === 'textarea'"
133
- v-bind="$attrs"
144
+ v-bind="elementAttributes"
134
145
  :id="labelId"
135
146
  :value="modelValue"
136
147
  :maxlength="getMaxLength()"
@@ -144,18 +155,18 @@
144
155
  <!-- begin searchfield -->
145
156
  <template v-else-if="element === 'input' && $attrs.type === 'search'">
146
157
  <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
158
  <input
149
- v-bind="$attrs"
159
+ v-bind="elementAttributes"
150
160
  :id="labelId"
151
161
  @input="onInput"
152
162
  :maxlength="$attrs.maxlength > 0 ? $attrs.maxlength : 255"
153
163
  :value="modelValue"
154
164
  />
165
+ <a v-if="showSearchButton" href="#" class="button no-flex" :title="iconSearch.tooltip" @click.prevent="executeSearch">
166
+ <span :class="iconSearch.iconClass"></span>
167
+ </a>
168
+ <a v-if="iconDelete.show" href="#" @click.prevent="$emit('update:modelValue', '')" :class="iconDelete.iconClass" :title="iconDelete.tooltip"></a>
155
169
  </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
170
  </template>
160
171
  </label>
161
172
  <!-- end searchfield -->
@@ -349,7 +360,7 @@ export default {
349
360
  *
350
361
  * may not be named as 'class' because it is a reserved keyword in JavaScript
351
362
  */
352
- htmlClass: {
363
+ inputClass: {
353
364
  type: String,
354
365
  required: false
355
366
  },
@@ -582,6 +593,19 @@ export default {
582
593
  },
583
594
  },
584
595
  computed: {
596
+ elementAttributes() {
597
+ const commonAttributes = ["name", "required", "readonly", "disabled", "autofocus"]
598
+ const attributes = {
599
+ input: [...commonAttributes, "type", "minlength", "pattern", "min", "max", "multiple", "step", "autocomplete", "placeholder"],
600
+ select: [...commonAttributes, "multiple"],
601
+ textarea: [...commonAttributes, "placeholder"]
602
+ }
603
+ const attrs = {}
604
+ if(attributes[this.element]) {
605
+ Object.entries(this.$attrs).filter(([name]) => attributes[this.element].includes(name)).forEach(([name, value]) => attrs[name] = value)
606
+ }
607
+ return attrs
608
+ },
585
609
  buttonAttrs() {
586
610
  // copy all native attributes
587
611
  const allAttrs = {...this.$attrs}
@@ -633,14 +657,14 @@ 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()
@@ -656,7 +680,7 @@ export default {
656
680
  }
657
681
 
658
682
  if (this.$attrs.type !== 'file') {
659
- return this.$attrs.maxlength > 0 ? this.$attrs.maxlength : 255
683
+ return this.$attrs.maxlength > 0 ? this.$attrs.maxlength : 255
660
684
  }
661
685
 
662
686
  return null
@@ -800,15 +824,17 @@ export default {
800
824
  .search-field-wrapper {
801
825
  margin: 0;
802
826
 
803
- a {
827
+ a[class*="icon"] {
804
828
  position: absolute;
805
829
  top: 50%;
806
830
  right: 1rem;
807
831
  transform: translateY(-50%);
808
832
  z-index: 100;
833
+ }
809
834
 
810
- & + input {
811
- padding-right: calc(var(--default-padding) * 3);
835
+ a.button {
836
+ & + a[class*="icon"] {
837
+ right: 5rem;
812
838
  }
813
839
  }
814
840
  }
@@ -816,7 +842,6 @@ export default {
816
842
  .place-inside {
817
843
  + .search-field-wrapper {
818
844
 
819
-
820
845
  input {
821
846
  padding-left: calc(var(--default-padding) * 3);
822
847
  }
@@ -824,29 +849,11 @@ export default {
824
849
  }
825
850
 
826
851
  /* begin toggle-switch */
827
- /* no cmd-prefix-styling (class based on frontend-framework */
852
+ /* no cmd-prefix-styling (class based on frontend-framework) */
828
853
  &.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 {
854
+ &.colored {
855
+ &.off {
856
+ .switch-label-wrapper {
850
857
  border-color: var(--error-color);
851
858
 
852
859
  span {
@@ -860,8 +867,10 @@ export default {
860
867
  }
861
868
  }
862
869
  }
870
+ }
863
871
 
864
- &.on {
872
+ &.on {
873
+ .switch-label-wrapper {
865
874
  border-color: var(--success-color);
866
875
 
867
876
  span {
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <div class="cmd-input-group">
3
- <span :class="['label', { hidden: !showLabel, inline: labelInline }]">{{ labelText }}</span>
2
+ <div :class="['cmd-input-group', {inline: labelInline}]">
3
+ <span :class="['label', { hidden: !showLabel}]">{{ labelText }}</span>
4
4
  <div class="flex-container no-flex">
5
5
  <slot></slot>
6
6
  </div>
@@ -35,4 +35,13 @@ export default {
35
35
  }
36
36
  }
37
37
  }
38
- </script>
38
+ </script>
39
+
40
+ <style lang="scss">
41
+ .cmd-input-group {
42
+ &.inline {
43
+ display: flex;
44
+ gap: var(--default-gap);
45
+ }
46
+ }
47
+ </style>
@@ -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") {
@@ -183,7 +183,7 @@ export default {
183
183
  background: var(--primary-color);
184
184
 
185
185
  span, span[class*='icon'] {
186
- color: var(--pure-white);
186
+ color: var(--color-scheme-text-color);
187
187
  }
188
188
  }
189
189
 
@@ -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 {
@@ -1,7 +1,9 @@
1
1
  <template>
2
2
  <div :class="['cmd-site-header', { sticky: sticky }]" role="banner">
3
3
  <!-- begin slot for elements above header -->
4
- <slot name="top-header"></slot>
4
+ <div class="top-header">
5
+ <slot name="top-header"></slot>
6
+ </div>
5
7
  <!-- end for elements above header -->
6
8
 
7
9
  <!-- begin header-wrapper with slots for logo and other header elements -->
@@ -73,20 +75,27 @@ export default {
73
75
  display: flex;
74
76
  flex-direction: column;
75
77
  border-bottom: var(--default-border);
76
- background: var(--pure-white);
78
+ background: var(--color-scheme-background-color);
77
79
 
78
80
  &.sticky {
79
81
  position: sticky;
80
82
  z-index: 300;
81
83
  }
82
84
 
83
- header, .cmd-main-navigation nav, .cmd-list-of-links > ul {
85
+ header, .cmd-main-navigation nav, .cmd-list-of-links {
84
86
  max-width: var(--max-width);
85
87
  width: 100%; /* stretch flex-item */
86
88
  margin: 0 auto;
87
89
  padding: 0 var(--default-padding);
88
90
  }
89
91
 
92
+ .top-header {
93
+ .cmd-list-of-links {
94
+ padding-top: calc(var(--default-padding) / 2);
95
+ padding-bottom: calc(var(--default-padding) / 2);
96
+ }
97
+ }
98
+
90
99
  > .cmd-main-navigation:last-child {
91
100
  border-bottom: 0;
92
101
  }
@@ -109,7 +109,7 @@ export default {
109
109
  border-top-left-radius: var(--border-radius);
110
110
  border-top-right-radius: var(--border-radius);
111
111
  list-style-type: none;
112
- background: var(--pure-white);
112
+ background: var(--color-scheme-background-color);
113
113
  border: var(--default-border);
114
114
 
115
115
  &.active {
@@ -125,7 +125,7 @@ export default {
125
125
  a {
126
126
  display: block;
127
127
  padding: var(--default-padding);
128
- color: var(--text-color);
128
+ color: var(--color-scheme-text-color);
129
129
 
130
130
  &:hover, &:active, &:focus {
131
131
  cursor: pointer;
@@ -154,7 +154,7 @@ export default {
154
154
  padding: var(--default-padding);
155
155
  border: var(--primary-border);
156
156
  border-radius: var(--border-radius);
157
- background: var(--pure-white);
157
+ background: var(--color-scheme-background-color);
158
158
  border-top-left-radius: 0;
159
159
 
160
160
  > div {
@@ -148,7 +148,7 @@ export default {
148
148
  display: table;
149
149
  margin: 0 auto calc(var(--default-margin) * 2) auto;
150
150
  border: var(--default-border);
151
- background: var(--pure-white);
151
+ background: var(--color-scheme-background-color);
152
152
 
153
153
  > ul {
154
154
  overflow: hidden;
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <div :class="['cmd-toggle-dark-mode', {'dark-mode': darkMode}]">
3
+ <CmdFormElement
4
+ element="input"
5
+ type="checkbox"
6
+ :labelText="labelText"
7
+ :showLabel="showLabel"
8
+ v-model="darkMode"
9
+ />
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ import CmdFormElement from "./CmdFormElement"
15
+
16
+ export default {
17
+ data() {
18
+ return {
19
+ darkMode: false
20
+ }
21
+ },
22
+ components: {
23
+ CmdFormElement
24
+ },
25
+ props: {
26
+ labelText: {
27
+ type: String,
28
+ default: "Toggle Darkmode"
29
+ },
30
+ showLabel: {
31
+ type: Boolean,
32
+ default: false
33
+ }
34
+ },
35
+ created() {
36
+ // get color-scheme (light-/dark-mode) from browser-settings
37
+ // this.darkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
38
+ // document.body.classList.add(this.darkMode ? 'dark-mode' : 'light-mode');
39
+
40
+ const mql = window.matchMedia('(prefers-color-scheme: dark)')
41
+ mql.addEventListener("change", this.onColorSchemeChange)
42
+ this.onColorSchemeChange(mql)
43
+ },
44
+ beforeUnmount() {
45
+ window.matchMedia('(prefers-color-scheme: dark)').removeEventListener("change", this.onColorSchemeChange)
46
+ },
47
+ methods: {
48
+ onColorSchemeChange(event) {
49
+ this.darkMode = event.matches
50
+ document.querySelector('html').classList.add(this.darkMode ? 'dark-mode' : 'light-mode')
51
+ }
52
+ },
53
+ watch: {
54
+ darkMode() {
55
+ // toggle classes to overwrite media-query styles for color-schemes
56
+ const htmlTag = document.querySelector('html')
57
+ if(this.darkMode) {
58
+ htmlTag.classList.replace("light-mode", "dark-mode");
59
+ } else {
60
+ htmlTag.classList.replace("dark-mode", "light-mode");
61
+ }
62
+ htmlTag.dispatchEvent(new CustomEvent('toggle-color-scheme', { detail: this.darkMode ? 'dark-mode' : 'light-mode' }))
63
+ }
64
+ }
65
+ }
66
+ </script>
@@ -980,14 +980,13 @@ export default {
980
980
  <style lang="scss">
981
981
  /* begin cmd-upload-form -------------------------------------------------------------------------------------------- */
982
982
  .cmd-upload-form {
983
-
984
983
  .cmd-custom-headline {
985
984
  margin: 0;
986
985
  justify-content: center;
987
986
  }
988
987
 
989
988
  .box {
990
- background: var(--pure-white-reduced-opacity);
989
+ background: var(--color-scheme-background-color);
991
990
 
992
991
  dl {
993
992
  justify-content: center;
@@ -1031,7 +1030,7 @@ export default {
1031
1030
 
1032
1031
  progress {
1033
1032
  &[value] {
1034
- background: var(--pure-white);
1033
+ background: var(--color-scheme-background-color);
1035
1034
 
1036
1035
  &::-moz-progress-bar {
1037
1036
  border-top-left-radius: var(--border-radius);
@@ -1051,7 +1050,7 @@ export default {
1051
1050
  top: 0.2rem;
1052
1051
  padding: 0.1rem 0.2rem;
1053
1052
  line-height: 100%;
1054
- background: var(--pure-white);
1053
+ background: var(--color-scheme-background-color);
1055
1054
  }
1056
1055
  }
1057
1056
  }
@@ -1119,7 +1118,7 @@ export default {
1119
1118
  .drop-area {
1120
1119
  border: var(--default-border);
1121
1120
  border-style: dashed;
1122
- background: var(--pure-white);
1121
+ background: var(--color-scheme-background-color);
1123
1122
  padding: (var(--default-padding));
1124
1123
  text-align: center;
1125
1124
 
package/src/index.js CHANGED
@@ -32,7 +32,6 @@ export { default as CmdShareButtons } from '@/components/CmdShareButtons'
32
32
  export { default as CmdSiteHeader } from '@/components/CmdSiteHeader'
33
33
  export { default as CmdSlideButton } from '@/components/CmdSlideButton'
34
34
  export { default as CmdSlideshow } from '@/components/CmdSlideshow'
35
- export { default as CmdSwitchButton } from '@/components/CmdSwitchButton'
36
35
  export { default as CmdSwitchLanguage } from '@/components/CmdSwitchLanguage'
37
36
  export { default as CmdSystemMessage } from '@/components/CmdSystemMessage'
38
37
  export { default as CmdTable } from '@/components/CmdTable'