comand-component-library 3.1.69 → 3.1.72

Sign up to get free protection for your applications and to get access to all the features.
@@ -19,50 +19,81 @@
19
19
 
20
20
  <!-- begin label-text (+ required asterisk) -->
21
21
  <span v-if="labelText && $attrs.type !== 'checkbox' && $attrs.type !== 'radio'"
22
- :class="!showLabel ? 'hidden' : undefined">
23
- <span>
24
- {{ labelText }}<sup v-if="$attrs.required">*</sup>
25
- </span>
26
- <a v-if="$attrs.required || inputRequirements.length"
27
- href="#"
28
- @click.prevent
29
- :class="getStatusIconClass"
30
- :title="validationTooltip"
31
- :aria-errormessage="getValidationMessage"
32
- aria-live="assertive"
33
- :id="tooltipId"
34
- :role="validationStatus === 'error' ? 'alert' : 'dialog'">
35
- </a>
36
- </span>
22
+ :class="['label-text', !showLabel ? 'hidden' : undefined]">
23
+ <span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
24
+
25
+ <!-- begin CmdTooltip -->
26
+ <CmdTooltip v-if="useCustomTooltip" class="box" :class="validationStatus" :relatedId="tooltipId" :toggle-visibility-by-click="true">
27
+ <!-- begin CmdSystemMessage -->
28
+ <CmdSystemMessage
29
+ v-if="getValidationMessage"
30
+ :message="getValidationMessage"
31
+ :validation-status="validationStatus"
32
+ :iconClose="{show: false}"
33
+ />
34
+ <!-- end CmdSystemMessage -->
35
+
36
+ <template v-if="showRequirements && (validationStatus === '' || validationStatus === 'error')">
37
+ <!-- begin list of requirements -->
38
+ <h6>
39
+ {{ getMessage("cmdformelement.headline.requirements_for_input") }}<br/>
40
+ "{{ labelText }}"
41
+ </h6>
42
+ <dl class="list-of-requirements">
43
+ <template v-for="(requirement, index) in inputRequirements" :key="index">
44
+ <dt aria-live="assertive" :class="requirement.valid(modelValue, $attrs) ? 'success' : 'error'">{{ requirement.message }}:</dt>
45
+ <dd :class="requirement.valid(modelValue, $attrs) ? 'success' : 'error'">
46
+ <span aria-live="assertive" :class="requirement.valid(modelValue, $attrs) ? iconHasStateSuccess.iconClass : iconHasStateError.iconClass"
47
+ :title="requirement.valid(modelValue, $attrs) ? iconHasStateSuccess.tooltip : iconHasStateError.tooltip"></span>
48
+ </dd>
49
+ </template>
50
+ </dl>
51
+ <!-- end list of requirements -->
52
+
53
+ <!-- begin helplink -->
54
+ <hr v-if="helplink?.show"/>
55
+ <a v-if="helplink?.show && helplink?.url" :href="helplink.url" :target="helplink.target" @click.prevent>
56
+ <span v-if="helplink.icon?.iconClass" :class="helplink.icon?.iconClass" :title="helplink.icon?.tooltip"></span>
57
+ <span v-if="helplink.text">{{ helplink.text }}</span>
58
+ </a>
59
+ <!-- end helplink -->
60
+ </template>
61
+ </CmdTooltip>
62
+ <!-- end CmdTooltip -->
63
+
64
+ <a v-if="$attrs.required || inputRequirements.length"
65
+ href="#"
66
+ @click.prevent
67
+ :class="getStatusIconClass"
68
+ :title="validationTooltip"
69
+ :aria-errormessage="getValidationMessage"
70
+ aria-live="assertive"
71
+ :id="tooltipId"
72
+ :role="validationStatus === 'error' ? 'alert' : 'dialog'">
73
+ </a>
74
+ </span>
37
75
  <!-- end label-text (+ required asterisk) -->
38
76
 
39
- <!-- begin icon -->
40
- <span
41
- v-if="
42
- $attrs.type !== 'checkbox' &&
43
- $attrs.type !== 'radio' &&
44
- fieldIconClass
45
- "
46
- :class="['place-inside', fieldIconClass]"
47
- ></span>
48
- <!-- end icon -->
77
+ <!-- begin icon inside field -->
78
+ <span v-if="$attrs.type !== 'checkbox' && $attrs.type !== 'radio' && fieldIconClass" :class="['place-inside', fieldIconClass]"></span>
79
+ <!-- end icon inside field -->
49
80
 
50
81
  <!-- begin inputfield -->
51
- <template
52
- v-if="element === 'input' && $attrs.type !== 'checkbox' && $attrs.type !== 'radio' && $attrs.type !== 'search'">
53
- <input v-bind="elementAttributes"
54
- :id="labelId"
55
- :class="inputClass"
56
- @focus="tooltip = true"
57
- @blur="onBlur"
58
- @input="onInput"
59
- @mouseover="datalistFocus"
60
- @keyup="checkForCapsLock"
61
- :autocomplete="autocomplete"
62
- :list="datalist ? datalist.id : null"
63
- :value="modelValue"
64
- :maxlength="getMaxLength()"
65
- ref="input"
82
+ <template v-if="element === 'input' && $attrs.type !== 'checkbox' && $attrs.type !== 'radio' && $attrs.type !== 'search'">
83
+ <input
84
+ v-bind="elementAttributes"
85
+ :id="labelId"
86
+ :class="inputClass"
87
+ @focus="tooltip = true"
88
+ @blur="onBlur"
89
+ @input="onInput"
90
+ @mouseover="datalistFocus"
91
+ @keyup="checkForCapsLock"
92
+ :autocomplete="autocomplete"
93
+ :list="datalist ? datalist.id : null"
94
+ :value="modelValue"
95
+ :maxlength="getMaxLength()"
96
+ ref="input"
66
97
  />
67
98
  </template>
68
99
  <!-- end inputfield -->
@@ -90,18 +121,18 @@
90
121
  <!-- begin checkbox and radiobutton -->
91
122
  <template v-else-if="element === 'input' && ($attrs.type === 'checkbox' || $attrs.type === 'radio')">
92
123
  <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 }">
103
- <span v-if="labelText">{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
104
- </span>
124
+ <input
125
+ v-bind="elementAttributes"
126
+ @change="onChange"
127
+ @blur="onBlur"
128
+ :checked="isChecked"
129
+ :value="inputValue"
130
+ :class="[inputClass, validationStatus, toggleSwitchIconClass, { 'replace-input-type': replaceInputType, 'toggle-switch': toggleSwitch }]"
131
+ :id="labelId"
132
+ :disabled="$attrs.disabled"
133
+ :aria-invalid="validationStatus === 'error'"
134
+ />
135
+ <span v-if="labelText" :class="['label-text', { hidden: !showLabel }]"><span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span></span>
105
136
  </template>
106
137
  <!-- begin labels for toggle-switch with switch-label -->
107
138
  <template v-else-if="onLabel && offLabel">
@@ -113,12 +144,13 @@
113
144
  :value="inputValue"
114
145
  :class="{inputClass, validationStatus}"
115
146
  :id="labelId"
147
+ :disabled="$attrs.disabled"
116
148
  :aria-invalid="validationStatus === 'error'"
117
149
  />
118
- <span class="label">{{ onLabel }}</span>
119
- <span class="label">{{ offLabel }}</span>
150
+ <span class="label-text">{{ onLabel }}</span>
151
+ <span class="label-text">{{ offLabel }}</span>
120
152
  </span>
121
- <span v-if="labelText">
153
+ <span v-if="labelText" class="label-text">
122
154
  <span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
123
155
  </span>
124
156
  </template>
@@ -154,19 +186,19 @@
154
186
 
155
187
  <!-- begin searchfield -->
156
188
  <template v-else-if="element === 'input' && $attrs.type === 'search'">
157
- <div class="search-field-wrapper flex-container no-gap">
189
+ <span class="search-field-wrapper flex-container no-gap">
158
190
  <input
159
191
  v-bind="elementAttributes"
160
192
  :id="labelId"
161
193
  @input="onInput"
162
- :maxlength="$attrs.maxlength > 0 ? $attrs.maxlength : 255"
194
+ :maxlength="getMaxLength()"
163
195
  :value="modelValue"
164
196
  />
165
- <a v-if="showSearchButton" href="#" class="button no-flex" :title="iconSearch.tooltip" @click.prevent="executeSearch">
197
+ <a v-if="showSearchButton" href="#" :class="['button no-flex', {disabled: $attrs.disabled}]" :title="iconSearch.tooltip" @click.prevent="executeSearch">
166
198
  <span :class="iconSearch.iconClass"></span>
167
199
  </a>
168
200
  <a v-if="iconDelete.show" href="#" @click.prevent="$emit('update:modelValue', '')" :class="iconDelete.iconClass" :title="iconDelete.tooltip"></a>
169
- </div>
201
+ </span>
170
202
  </template>
171
203
  </label>
172
204
  <!-- end searchfield -->
@@ -181,45 +213,6 @@
181
213
  <span v-if="nativeButton?.icon?.show && nativeButton?.icon?.position === 'after'" :class="nativeButton?.icon?.iconClass"></span>
182
214
  </button>
183
215
  <!-- end button -->
184
-
185
- <!-- begin CmdTooltip -->
186
- <CmdTooltip v-if="useCustomTooltip" class="box" :class="validationStatus" :relatedId="tooltipId" :toggle-visibility-by-click="true">
187
- <!-- begin CmdSystemMessage -->
188
- <CmdSystemMessage
189
- v-if="getValidationMessage"
190
- :message="getValidationMessage"
191
- :validation-status="validationStatus"
192
- :iconClose="{show: false}"
193
- />
194
- <!-- end CmdSystemMessage -->
195
-
196
- <template v-if="showRequirements && (validationStatus === '' || validationStatus === 'error')">
197
- <!-- begin list of requirements -->
198
- <h6>
199
- {{ getMessage("cmdformelement.headline.requirements_for_input") }}<br/>
200
- "{{ labelText }}"
201
- </h6>
202
- <dl class="list-of-requirements">
203
- <template v-for="(requirement, index) in inputRequirements" :key="index">
204
- <dt aria-live="assertive" :class="requirement.valid(modelValue, $attrs) ? 'success' : 'error'">{{ requirement.message }}:</dt>
205
- <dd :class="requirement.valid(modelValue, $attrs) ? 'success' : 'error'">
206
- <span aria-live="assertive" :class="requirement.valid(modelValue, $attrs) ? iconHasStateSuccess.iconClass : iconHasStateError.iconClass"
207
- :title="requirement.valid(modelValue, $attrs) ? iconHasStateSuccess.tooltip : iconHasStateError.tooltip"></span>
208
- </dd>
209
- </template>
210
- </dl>
211
- <!-- end list of requirements -->
212
-
213
- <!-- begin helplink -->
214
- <hr v-if="helplink?.show"/>
215
- <a v-if="helplink?.show && helplink?.url" :href="helplink.url" :target="helplink.target" @click.prevent>
216
- <span v-if="helplink.icon?.iconClass" :class="helplink.icon?.iconClass" :title="helplink.icon?.tooltip"></span>
217
- <span v-if="helplink.text">{{ helplink.text }}</span>
218
- </a>
219
- <!-- end helplink -->
220
- </template>
221
- </CmdTooltip>
222
- <!-- end CmdTooltip -->
223
216
  </template>
224
217
 
225
218
  <script>
@@ -228,7 +221,7 @@ import {createUuid} from "../utils/common.js"
228
221
 
229
222
  // import mixins
230
223
  import I18n from "../mixins/I18n"
231
- import DefaultMessageProperties from "../mixins/CmdBox/DefaultMessageProperties"
224
+ import DefaultMessageProperties from "../mixins/CmdFormElement/DefaultMessageProperties"
232
225
  import FieldValidation from "../mixins/FieldValidation.js"
233
226
  import Tooltip from "../mixins/Tooltip.js"
234
227
 
@@ -343,7 +336,7 @@ export default {
343
336
  * allow checkbox/radio-buttons to get value from outside
344
337
  */
345
338
  inputValue: {
346
- type: String,
339
+ type: [String, Number],
347
340
  required: false
348
341
  },
349
342
  /**
@@ -558,6 +551,33 @@ export default {
558
551
  }
559
552
  }
560
553
  },
554
+ /**
555
+ * toggle if toggle-switch shows icons for checked/unchecked-status
556
+ */
557
+ useIconsForToggleSwitch: {
558
+ type: Boolean,
559
+ default: false
560
+ },
561
+ /**
562
+ * icon for toggle-switch checked
563
+ *
564
+ * toggle-switch-property must be activated
565
+ * use-icons-for-toggle-switch-property must be activated
566
+ */
567
+ toggleSwitchCheckedIconClass: {
568
+ type: String,
569
+ default: "icon-check-circle"
570
+ },
571
+ /**
572
+ * icon for toggle-switch unchecked
573
+ *
574
+ * toggle-switch-property must be activated
575
+ * use-icons-for-toggle-switch-property must be activated
576
+ */
577
+ toggleSwitchUncheckedIconClass: {
578
+ type: String,
579
+ default: "icon-cancel-circle"
580
+ },
561
581
  /**
562
582
  * icon to toggle password-visibility
563
583
  *
@@ -601,7 +621,7 @@ export default {
601
621
  textarea: [...commonAttributes, "placeholder"]
602
622
  }
603
623
  const attrs = {}
604
- if(attributes[this.element]) {
624
+ if (attributes[this.element]) {
605
625
  Object.entries(this.$attrs).filter(([name]) => attributes[this.element].includes(name)).forEach(([name, value]) => attrs[name] = value)
606
626
  }
607
627
  return attrs
@@ -668,21 +688,31 @@ export default {
668
688
  return this.$attrs.id
669
689
  }
670
690
  return "label-" + createUuid()
691
+ },
692
+ // toggle icons for toggle-switch
693
+ toggleSwitchIconClass() {
694
+ if(this.toggleSwitch && this.useIconsForToggleSwitch && this.toggleSwitchUncheckedIconClass && this.toggleSwitchCheckedIconClass) {
695
+ if(this.isChecked) {
696
+ return this.toggleSwitchCheckedIconClass
697
+ }
698
+ return this.toggleSwitchUncheckedIconClass
699
+ }
700
+ return null
671
701
  }
672
702
  },
673
703
  methods: {
674
704
  getDomElement() {
675
705
  return this.$refs.label
676
706
  },
707
+ // define max-length for different input-types
677
708
  getMaxLength() {
678
709
  if (this.$attrs.element === 'textarea') {
679
710
  return this.$attrs.maxlength > 0 ? this.$attrs.maxlength : 5000
680
711
  }
681
712
 
682
- if (this.$attrs.type !== 'file') {
713
+ if (this.$attrs.type !== 'file' && this.$attrs.type !== 'number' && this.$attrs.type !== 'date') {
683
714
  return this.$attrs.maxlength > 0 ? this.$attrs.maxlength : 255
684
715
  }
685
-
686
716
  return null
687
717
  },
688
718
  onBlur(event) {
@@ -773,29 +803,22 @@ export default {
773
803
  </script>
774
804
 
775
805
  <style lang="scss">
806
+ /* begin cmd-form-element ------------------------------------------------------------------------------------------ */
776
807
  .cmd-form-element {
777
808
  input + .place-inside[class*="icon"] {
778
809
  left: auto;
779
810
  right: .5rem
780
811
  }
781
812
 
782
- &.has-state, & + .cmd-tooltip {
783
- &.error {
784
- --status-color: var(--error-color);
785
- }
786
-
787
- &.warning {
788
- --status-color: var(--warning-color);
789
- }
790
-
791
- &.success {
792
- --status-color: var(--success-color);
793
- }
794
-
795
- &.info {
796
- --status-color: var(--info-color);
797
- }
813
+ .cmd-tooltip {
814
+ position: absolute;
815
+ right: 0;
816
+ transform: translateY(calc(-100% - calc(var(--default-margin) / 2)));
817
+ left: auto !important;
818
+ top: 0 !important;
819
+ }
798
820
 
821
+ &.has-state, & + .cmd-tooltip {
799
822
  ::placeholder {
800
823
  color: var(--status-color);
801
824
  }
@@ -809,13 +832,9 @@ export default {
809
832
  }
810
833
  }
811
834
 
812
- & + .cmd-tooltip {
813
- border-color: var(--status-color);
814
- }
815
-
816
835
  &.inline {
817
836
  & > span {
818
- & > a {
837
+ & > a:not(.button) {
819
838
  margin-left: calc(var(--default-margin) / 2);
820
839
  }
821
840
  }
@@ -841,7 +860,6 @@ export default {
841
860
 
842
861
  .place-inside {
843
862
  + .search-field-wrapper {
844
-
845
863
  input {
846
864
  padding-left: calc(var(--default-padding) * 3);
847
865
  }
@@ -857,7 +875,7 @@ export default {
857
875
  border-color: var(--error-color);
858
876
 
859
877
  span {
860
- &.label {
878
+ &.label-text {
861
879
  color: var(--error-color);
862
880
 
863
881
  &::before {
@@ -874,7 +892,7 @@ export default {
874
892
  border-color: var(--success-color);
875
893
 
876
894
  span {
877
- &.label {
895
+ &.label-text {
878
896
  color: var(--success-color);
879
897
 
880
898
  &::before {
@@ -887,7 +905,7 @@ export default {
887
905
  }
888
906
  }
889
907
  }
890
-
891
- /* end toggle-switch ------------------------------------------------------------------------------------------ */
908
+ /* end toggle-switch */
892
909
  }
910
+ /* end cmd-form-element------------------------------------------------------------------------------------------ */
893
911
  </style>
@@ -1,15 +1,94 @@
1
1
  <template>
2
- <div :class="['cmd-input-group', {inline: labelInline}]">
3
- <span :class="['label', { hidden: !showLabel}]">{{ labelText }}</span>
4
- <div class="flex-container no-flex">
2
+ <div :class="['cmd-input-group label', {inline: labelInline, 'multiple-switch': multipleSwitch, disabled: disabled}]">
3
+ <span :class="['label-text', { hidden: !showLabel}]" :id="labelId" :aria-labelledby="labelId">
4
+ <span>{{ labelText }}<sup v-if="$attrs.required">*</sup></span>
5
+ </span>
6
+ <span v-if="!useSlot" :class="['flex-container', {'no-flex': !stretchHorizontally, 'no-gap': multipleSwitch}]">
7
+ <label v-for="(inputElement, index) in inputElements" :key="index" :for="inputElement.id">
8
+ <input
9
+ :type="inputTypes"
10
+ :id="inputElement.id"
11
+ :name="inputElement.name"
12
+ :value="inputElement.value"
13
+ v-model="inputValue"
14
+ :disabled="disabled"
15
+ :class="{'replace-input-type': replaceInputType}"
16
+ />
17
+ <span v-if="multipleSwitch && inputElement.iconClass" :class="inputElement.iconClass"></span>
18
+ <span v-if="inputElement.labelText">{{ inputElement.labelText }}</span>
19
+ </label>
20
+ </span>
21
+
22
+ <!-- begin useSlot -->
23
+ <div v-else class="flex-container no-flex">
24
+ <!-- begin slot -->
5
25
  <slot></slot>
26
+ <!-- end slot -->
6
27
  </div>
28
+ <!-- end useSlot -->
7
29
  </div>
8
30
  </template>
9
31
 
10
32
  <script>
33
+ import {createUuid} from "../utils/common"
34
+
11
35
  export default {
36
+ data() {
37
+ return {
38
+ value: ""
39
+ }
40
+ },
12
41
  props: {
42
+ /**
43
+ * set value for v-model (must be named modelValue in vue3 if default v-model should be used)
44
+ */
45
+ modelValue: {
46
+ type: [Array, String],
47
+ required: false
48
+ },
49
+ /**
50
+ * list of input-elements inside group
51
+ *
52
+ * useSlot-property must be set to 'false'
53
+ */
54
+ inputElements: {
55
+ type: Array,
56
+ required: false
57
+ },
58
+ /**
59
+ * set type for inputs in group
60
+ *
61
+ * @allowedValues: checkbox, radio
62
+ */
63
+ inputTypes: {
64
+ type: String,
65
+ default: "radio"
66
+ },
67
+ /**
68
+ * for replacing native checkboxes/radio-buttons by custom ones (based on frontend-framework)
69
+ *
70
+ * @affectsStyling: true
71
+ */
72
+ replaceInputType: {
73
+ type: Boolean,
74
+ default: false
75
+ },
76
+ /**
77
+ * activate if input-elements should be given by slot
78
+ */
79
+ useSlot: {
80
+ type: Boolean,
81
+ default: false
82
+ },
83
+ /**
84
+ * toggle multipleSwitch-styling
85
+ *
86
+ * @affectsStyling: true
87
+ */
88
+ multipleSwitch: {
89
+ type: Boolean,
90
+ default: false
91
+ },
13
92
  /**
14
93
  * toggle label-text visibility
15
94
  */
@@ -32,6 +111,58 @@ export default {
32
111
  labelInline: {
33
112
  type: Boolean,
34
113
  default: false
114
+ },
115
+ /**
116
+ * toggle if input-elements will be stretched horizontally
117
+ *
118
+ * @affectsStyling: true
119
+ */
120
+ stretchHorizontally: {
121
+ type: Boolean,
122
+ default: false
123
+ },
124
+ /**
125
+ * define disabled-property to set disabled-style
126
+ *
127
+ * component cannot handle native disabled-attribute, because it is no native form-element
128
+ */
129
+ disabled: {
130
+ type: Boolean,
131
+ default: false
132
+ }
133
+ },
134
+ computed: {
135
+ // get ID for accessibility
136
+ labelId() {
137
+ if(this.$attrs.id !== undefined) {
138
+ return this.$attrs.id
139
+ }
140
+ return "label-" + createUuid()
141
+ },
142
+ inputValue: {
143
+ // read inputValue
144
+ get() {
145
+ return this.modelValue
146
+ },
147
+ // set/write a value to update v-model for this component
148
+ set(value) {
149
+ this.$emit("update:modelValue", value)
150
+ }
151
+ }
152
+ },
153
+ methods: {
154
+ onChange(e) {
155
+ if (typeof this.value === "string") {
156
+ this.$emit("update:value", e.target.value)
157
+ } else if (this.value !== undefined) {
158
+ let values = [...this.value]
159
+ if (e.target.checked) {
160
+ values.push(e.target.value)
161
+ } else {
162
+ values = values.filter(value => value !== e.target.value)
163
+ }
164
+ this.$emit("update:modelValue", values)
165
+ }
35
166
  }
36
167
  }
37
168
  }
@@ -183,7 +183,7 @@ export default {
183
183
  background: var(--primary-color);
184
184
 
185
185
  span, span[class*='icon'] {
186
- color: var(--color-scheme-text-color);
186
+ color: var(--pure-white);
187
187
  }
188
188
  }
189
189
 
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <label class="cmd-progressbar" :for="id">
3
- <span :class="{hidden: !showLabel}">{{ labelText }}</span>
3
+ <span :class="['label-text', {hidden: !showLabel}]">{{ labelText }}</span>
4
4
  <span class="progressbar">
5
- <span v-if="showLoadingStatus">{{ loadingStatus }}%</span><!-- do not place inside progress-tag (will not be displayed then) -->
5
+ <span v-if="showLoadingStatus">{{ loadingStatus }} %</span><!-- do not place inside progress-tag (will not be displayed then) -->
6
6
  <progress v-bind="$attrs" :id="id" :value="loadingStatus"></progress>
7
7
  </span>
8
8
  </label>
@@ -133,7 +133,7 @@ export default {
133
133
  type: Object,
134
134
  default: function () {
135
135
  return {
136
- iconClass: "icon-table",
136
+ iconClass: "icon-toggle-table-width",
137
137
  tooltip: "Toggle table width"
138
138
  }
139
139
  }
@@ -116,10 +116,6 @@ export default {
116
116
  border-bottom: 0;
117
117
  border-color: var(--primary-color);
118
118
  top: .1rem;
119
-
120
- a {
121
- color: var(--primary-color);
122
- }
123
119
  }
124
120
 
125
121
  a {