@vcmap/ui 5.0.0-rc.8 → 5.0.0-rc.9

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 (178) hide show
  1. package/README.md +69 -22
  2. package/build/build.js +0 -3
  3. package/build/buildHelpers.js +0 -1
  4. package/build/commonViteConfig.js +1 -1
  5. package/config/dev.config.json +4 -4
  6. package/dist/assets/{cesium.6b5bb6.js → cesium.4e40f4.js} +0 -0
  7. package/dist/assets/cesium.js +1 -1
  8. package/dist/assets/core.edcf5e.js +4 -0
  9. package/dist/assets/core.js +1 -1
  10. package/dist/assets/{index.0be2842f.js → index.889d0f3a.js} +1 -1
  11. package/dist/assets/{ol.0561aa.js → ol.246fd4.js} +0 -0
  12. package/dist/assets/ol.js +1 -1
  13. package/dist/assets/ui.df4f6d.css +1 -0
  14. package/dist/assets/ui.df4f6d.js +43 -0
  15. package/dist/assets/ui.js +1 -1
  16. package/dist/assets/{vue-composition-api.f926fa.js → vue-composition-api.a520f3.js} +1 -1
  17. package/dist/assets/vue-composition-api.js +2 -2
  18. package/dist/assets/{vue.ddcb6b.js → vue.2cee44.js} +0 -0
  19. package/dist/assets/vue.js +1 -1
  20. package/dist/assets/{vuetify.d21163.css → vuetify.cc817b.css} +0 -0
  21. package/dist/assets/{vuetify.d21163.js → vuetify.cc817b.js} +1 -1
  22. package/dist/assets/vuetify.js +2 -2
  23. package/dist/index.html +1 -1
  24. package/index.js +39 -1
  25. package/package.json +2 -3
  26. package/plugins/@vcmap/pluginExample/index.js +5 -5
  27. package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +1 -1
  28. package/plugins/@vcmap/project-selector/ContextsListComponent.vue +1 -1
  29. package/plugins/@vcmap/project-selector/index.js +5 -5
  30. package/plugins/@vcmap/project-selector/package.json +1 -2
  31. package/plugins/@vcmap/theme-changer/index.js +6 -6
  32. package/plugins/buttonExamples/ButtonExamples.vue +1 -1
  33. package/plugins/buttonExamples/index.js +5 -4
  34. package/plugins/categoryTest/Categories.vue +1 -1
  35. package/plugins/categoryTest/Category.vue +1 -1
  36. package/plugins/categoryTest/index.js +5 -5
  37. package/plugins/example/index.js +33 -14
  38. package/plugins/test/allIconsComponent.vue +34 -0
  39. package/plugins/test/editor.vue +1 -1
  40. package/plugins/test/index.js +40 -17
  41. package/plugins/test/toolbox-data.js +106 -26
  42. package/plugins/test/windowManagerExample.vue +1 -2
  43. package/src/actions/actionHelper.js +2 -1
  44. package/src/actions/styleSelector.vue +1 -1
  45. package/src/application/Navbar.vue +18 -6
  46. package/src/application/VcsApp.vue +34 -28
  47. package/src/assets/logo-mobile.svg +9 -0
  48. package/src/assets/logo.svg +23 -23
  49. package/src/components/buttons/VcsActionButtonList.vue +99 -0
  50. package/src/components/buttons/VcsButton.vue +201 -0
  51. package/src/components/form-inputs-controls/VcsCheckbox.vue +73 -0
  52. package/src/components/form-inputs-controls/VcsColorPicker.vue +81 -0
  53. package/src/components/form-inputs-controls/VcsFormSection.vue +46 -0
  54. package/src/components/form-inputs-controls/VcsLabel.vue +38 -0
  55. package/src/components/form-inputs-controls/VcsSelect.vue +97 -0
  56. package/src/components/form-inputs-controls/VcsTextArea.vue +130 -0
  57. package/src/components/form-inputs-controls/VcsTextField.vue +129 -0
  58. package/src/components/form-output/VcsFormattedNumber.vue +103 -0
  59. package/src/components/lists/VcsActionList.vue +100 -0
  60. package/src/components/lists/VcsTreeview.vue +109 -0
  61. package/src/components/lists/VcsTreeviewLeaf.vue +105 -0
  62. package/src/components/lists/VcsTreeviewSearchbar.vue +156 -0
  63. package/src/components/notification/VcsBadge.vue +27 -0
  64. package/src/components/notification/VcsTooltip.vue +154 -0
  65. package/src/components/notification/validation.js +19 -0
  66. package/src/contentTree/LayerTree.vue +1 -1
  67. package/src/contentTree/contentTreeCollection.js +6 -2
  68. package/src/icons/+all.js +359 -0
  69. package/src/icons/2DAreaIcon.vue +21 -0
  70. package/src/icons/2DDistanceIcon.vue +18 -0
  71. package/src/icons/3DAreaIcon.vue +21 -0
  72. package/src/icons/3DDistanceIcon.vue +18 -0
  73. package/src/icons/3DHeightIcon.vue +18 -0
  74. package/src/icons/AngleIcon.vue +8 -0
  75. package/src/icons/AssociationsIcon.vue +34 -0
  76. package/src/icons/AxisIcon.vue +10 -0
  77. package/src/icons/BoundingBoxIcon.vue +15 -0
  78. package/src/icons/CheckboxCheckedIcon.vue +16 -0
  79. package/src/icons/CheckboxIcon.vue +23 -0
  80. package/src/icons/CheckboxIndeterminateIcon.vue +24 -0
  81. package/src/icons/CircleIcon.vue +10 -0
  82. package/src/icons/ColorSwatchIcon.vue +17 -0
  83. package/src/icons/CommentIcon.vue +19 -0
  84. package/src/icons/CompassIcon.vue +8 -0
  85. package/src/icons/ComponentsIcon.vue +7 -0
  86. package/src/icons/ConeIcon.vue +11 -0
  87. package/src/icons/DimensionsHouseIcon.vue +14 -0
  88. package/src/icons/ElevationProfileIcon.vue +111 -0
  89. package/src/icons/ExportAreaIcon.vue +7 -0
  90. package/src/icons/ExportFlightIcon.vue +7 -0
  91. package/src/icons/ExportIcon.vue +8 -0
  92. package/src/icons/ExternalLinkIcon.vue +10 -0
  93. package/src/icons/EyeIcon.vue +7 -0
  94. package/src/icons/FastForwardIcon.vue +7 -0
  95. package/src/icons/FilterIcon.vue +8 -0
  96. package/src/icons/GlobeNatureIcon.vue +14 -0
  97. package/src/icons/HealthCareIndustriesIcon.vue +118 -0
  98. package/src/icons/HelpIcon.vue +7 -0
  99. package/src/icons/HomePointIcon.vue +8 -0
  100. package/src/icons/HospitalsIcon.vue +237 -0
  101. package/src/icons/HouseIcon.vue +25 -0
  102. package/src/icons/ImportIcon.vue +8 -0
  103. package/src/icons/InfoIcon.vue +10 -0
  104. package/src/icons/KebabIcon.vue +36 -0
  105. package/src/icons/LabelIcon.vue +7 -0
  106. package/src/icons/LayersIcon.vue +26 -0
  107. package/src/icons/LegendIcon.vue +65 -0
  108. package/src/icons/LineIcon.vue +7 -0
  109. package/src/icons/LinkIcon.vue +7 -0
  110. package/src/icons/MapIcon.vue +8 -0
  111. package/src/icons/MenuIcon.vue +34 -0
  112. package/src/icons/MinusIcon.vue +8 -0
  113. package/src/icons/ObjectAttributeIcon.vue +18 -0
  114. package/src/icons/ObjectSelectIcon.vue +8 -0
  115. package/src/icons/ObliqueViewIcon.vue +13 -0
  116. package/src/icons/PdfIcon.vue +10 -0
  117. package/src/icons/PedestrianIcon.vue +8 -0
  118. package/src/icons/PenIcon.vue +14 -0
  119. package/src/icons/PlayCircleIcon.vue +10 -0
  120. package/src/icons/PlusIcon.vue +9 -0
  121. package/src/icons/PoiIcon.vue +7 -0
  122. package/src/icons/PointSelectIcon.vue +7 -0
  123. package/src/icons/PolygonIcon.vue +38 -0
  124. package/src/icons/PresentationModeIcon.vue +7 -0
  125. package/src/icons/ProgressIcon.vue +24 -0
  126. package/src/icons/QueryIcon.vue +15 -0
  127. package/src/icons/RectangleIcon.vue +9 -0
  128. package/src/icons/ReturnIcon.vue +7 -0
  129. package/src/icons/RewindIcon.vue +6 -0
  130. package/src/icons/SearchIcon.vue +8 -0
  131. package/src/icons/ShadowIcon.vue +9 -0
  132. package/src/icons/ShapesIcon.vue +28 -0
  133. package/src/icons/ShareIcon.vue +22 -0
  134. package/src/icons/SimpleCircleFilledIcon.vue +15 -0
  135. package/src/icons/SimpleCircleHalfFilledIcon.vue +12 -0
  136. package/src/icons/SimpleCircleOutlinedIcon.vue +15 -0
  137. package/src/icons/SkipNextIcon.vue +7 -0
  138. package/src/icons/SkipPreviousIcon.vue +9 -0
  139. package/src/icons/SplitViewIcon.vue +19 -0
  140. package/src/icons/TextStyleIcon.vue +14 -0
  141. package/src/icons/ThreeDimensionsIcon.vue +7 -0
  142. package/src/icons/ToolsIcon.vue +35 -0
  143. package/src/icons/TouchIcon.vue +8 -0
  144. package/src/icons/TrashCanIcon.vue +7 -0
  145. package/src/icons/TriangleIcon.vue +15 -0
  146. package/src/icons/TwoDimensionsIcon.vue +8 -0
  147. package/src/icons/UploadIcon.vue +14 -0
  148. package/src/icons/VideoRecorderIcon.vue +14 -0
  149. package/src/icons/WalkingIcon.vue +7 -0
  150. package/src/icons/WallIcon.vue +14 -0
  151. package/src/manager/buttonManager.js +5 -53
  152. package/src/manager/navbarManager.js +81 -0
  153. package/src/manager/toolbox/ToolboxGroupComponent.vue +128 -0
  154. package/src/manager/toolbox/ToolboxManager.vue +119 -76
  155. package/src/manager/toolbox/toolboxManager.js +204 -0
  156. package/src/manager/window/WindowComponentHeader.vue +1 -1
  157. package/src/manager/window/WindowManager.vue +18 -1
  158. package/src/manager/window/windowManager.js +3 -5
  159. package/src/navigation/mapNavigation.vue +9 -5
  160. package/src/navigation/orientationToolsButton.vue +1 -1
  161. package/src/navigation/tiltSlider.vue +1 -1
  162. package/src/styles/_theming.scss +10 -0
  163. package/src/styles/main.scss +3 -0
  164. package/src/styles/variables.scss +70 -0
  165. package/src/styles/vcsFont.scss +5 -0
  166. package/src/styles/vcsGrid.scss +4 -0
  167. package/src/vcsUiApp.js +4 -3
  168. package/src/vuePlugins/vuetify.js +1 -1
  169. package/dist/assets/core.98f9bb.js +0 -4
  170. package/dist/assets/ui.b7c1e3.css +0 -1
  171. package/dist/assets/ui.b7c1e3.js +0 -39
  172. package/dist/assets/uicomponents.682c5f.css +0 -1
  173. package/dist/assets/uicomponents.682c5f.js +0 -32
  174. package/dist/assets/uicomponents.js +0 -1
  175. package/lib/uicomponents.js +0 -1
  176. package/src/manager/toolbox/ToolboxMultiSelectButton.vue +0 -96
  177. package/src/manager/toolbox/ToolboxSingleSelectButton.vue +0 -98
  178. package/src/manager/toolbox/toolbox-manager.js +0 -203
@@ -0,0 +1,201 @@
1
+ <template>
2
+ <div
3
+ class="vcs-button-wrap"
4
+ >
5
+ <VcsTooltip
6
+ :tooltip="tooltip"
7
+ :tooltip-position="tooltipPosition"
8
+ v-bind="{...tooltipProps}"
9
+ >
10
+ <template #activator="{ on, attrs }">
11
+ <v-btn
12
+ :color="backgroundColor"
13
+ :text="isTextButton"
14
+ :outlined="isOutlined"
15
+ :class="classes"
16
+ :ripple="!isSmall ? { class: 'primary--text text--darken-4' } : false"
17
+ elevation="0"
18
+ v-bind="{...$attrs, ...attrs}"
19
+ v-on="{...$listeners, ...on}"
20
+ >
21
+ <v-icon v-if="icon" v-text="icon" :class="{ 'mr-2': hasDefaultSlot }" />
22
+ <slot />
23
+ </v-btn>
24
+ </template>
25
+ </VcsTooltip>
26
+ <VcsBadge
27
+ v-if="hasUpdate"
28
+ :color="'warning'"
29
+ class="position-absolute"
30
+ />
31
+ </div>
32
+ </template>
33
+
34
+ <style lang="scss" scoped>
35
+ .vcs-button-wrap{
36
+ position: relative;
37
+ display: inline-block;
38
+ }
39
+ .badge{
40
+ top: -3px;
41
+ right: -3px;
42
+ }
43
+ .v-btn{
44
+ &--outlined{
45
+ border: thin solid currentColor;
46
+ }
47
+ &.vcs-button{
48
+
49
+ &--standard {
50
+ min-width: 48px;
51
+ height: 32px;
52
+ font-size: 12px;
53
+ border: 1px solid transparent;
54
+ &:hover{
55
+ color: var(--v-accent-lighten5) !important;
56
+ border-color: var(--v-primary-base);
57
+ background-color: var(--v-primary-base);
58
+ }
59
+ }
60
+
61
+ &--small {
62
+ height: 16px;
63
+ min-width: auto;
64
+ &:hover{
65
+ color: var(--v-primary-base);
66
+ }
67
+ &::before{
68
+ display: none; /*prevents unwanted mouseover effect*/
69
+ }
70
+ ::v-deep {
71
+ .v-icon{
72
+ font-size: 16px;
73
+ }
74
+
75
+ .v-icon__component {
76
+ height: 16px;
77
+ width: 16px;
78
+ }
79
+ }
80
+ }
81
+
82
+ &--large {
83
+ min-width: 42px;
84
+ height: 34px;
85
+ padding: 0;
86
+ position: relative;
87
+
88
+ &.vcs-button--active-disabled{
89
+ border: 2px solid var(--v-primary-base);
90
+ }
91
+ }
92
+ }
93
+ }
94
+ </style>
95
+
96
+ <script>
97
+ import VcsBadge from '../notification/VcsBadge.vue';
98
+ import VcsTooltip from '../notification/VcsTooltip.vue';
99
+
100
+ /**
101
+ * @description a button with tooltip extending {@link https://vuetifyjs.com/en/api/v-btn/|vuetify v-btn} using {@link VcsTooltip}.
102
+ * @vue-prop {boolean} active - Whether button has background color. Applies vuetify primary color if color property is not set.
103
+ * @vue-prop {string} color - Passes property to v-btn in case prop active is true.
104
+ * @vue-prop {boolean} hasUpdate - Whether the button shows a badge in the top right.
105
+ * @vue-prop {string} icon - When given, will display an icon in the button. Replaces vuetify icon property.
106
+ * @vue-prop {string} tooltip - Text content of a tooltip which appears on hover with default delay.
107
+ * @vue-prop {('bottom' | 'left' | 'top' | 'right')} tooltipPosition - Position of the tooltip.
108
+ * @vue-prop {Object<string, any>} tooltipProps - Properties to be passed to VcsTooltip {@link https://vuetifyjs.com/en/api/v-tooltip/#props|vuetify v-tooltip}
109
+ * @vue-computed {string} backgroundColor - color applied to button, depending on size and state
110
+ * @vue-computed {Object<string, string>} classes - css classes applied to button, depending on size and state
111
+ * @vue-computed {boolean} hasDefaultSlot
112
+ * @vue-computed {boolean} isSmall - button size is small
113
+ * @vue-computed {boolean} isStandard - button size standard
114
+ * @vue-computed {boolean} isLarge - button size is large
115
+ * @vue-computed {boolean} isOutlined - button is outlined
116
+ * @vue-computed {boolean} isTextButton - button is text
117
+ * @vue-event {MouseEvent} click - Emits click event when the button is clicked.
118
+ */
119
+ export default {
120
+ name: 'VcsButton',
121
+ components: { VcsTooltip, VcsBadge },
122
+ inheritAttrs: false,
123
+ props: {
124
+ active: {
125
+ type: Boolean,
126
+ default: false,
127
+ },
128
+ color: {
129
+ type: String,
130
+ default: undefined,
131
+ },
132
+ hasUpdate: {
133
+ type: Boolean,
134
+ default: false,
135
+ },
136
+ icon: {
137
+ type: String,
138
+ default: undefined,
139
+ },
140
+ tooltip: {
141
+ type: String,
142
+ default: undefined,
143
+ },
144
+ tooltipPosition: {
145
+ type: String,
146
+ default: 'bottom',
147
+ },
148
+ tooltipProps: {
149
+ type: Object,
150
+ default: () => ({}),
151
+ },
152
+ },
153
+ computed: {
154
+ backgroundColor() {
155
+ if (this.isStandard && !this.active) {
156
+ return this.color;
157
+ } else if (this.active) {
158
+ return this.color ? this.color : 'primary';
159
+ } else {
160
+ return null;
161
+ }
162
+ },
163
+ classes() {
164
+ return {
165
+ 'vcs-button--small': this.isSmall,
166
+ 'pa-0': this.isSmall,
167
+ 'vcs-button--standard': this.isStandard,
168
+ padding: this.isStandard,
169
+ 'font-weight-bold': this.isStandard,
170
+ 'text-capitalize': this.isStandard,
171
+ 'vcs-button--large': this.isLarge,
172
+ 'vcs-button--active-disabled': this.active && this.$attrs.disabled,
173
+ };
174
+ },
175
+ hasDefaultSlot() {
176
+ return !!this.$slots?.default?.[0]?.text?.trim();
177
+ },
178
+ isSmall() {
179
+ return this.$attrs.small != null;
180
+ },
181
+ isStandard() {
182
+ return !(this.isSmall || this.isLarge);
183
+ },
184
+ isLarge() {
185
+ return this.$attrs.large != null;
186
+ },
187
+ isOutlined() {
188
+ if (this.isStandard) {
189
+ return this.active || this.$attrs.disabled;
190
+ }
191
+ return false;
192
+ },
193
+ isTextButton() {
194
+ if (this.isSmall) {
195
+ return true;
196
+ }
197
+ return !this.active ? true : null;
198
+ },
199
+ },
200
+ };
201
+ </script>
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <VcsTooltip
3
+ :tooltip-position="tooltipPosition"
4
+ :tooltip="errorMessage"
5
+ color="error"
6
+ >
7
+ <template #activator="{ on, attrs }">
8
+ <span v-on="on">
9
+ <v-checkbox
10
+ on-icon="$vcsCheckboxChecked"
11
+ off-icon="$vcsCheckbox"
12
+ hide-details
13
+ indeterminate-icon="$vcsCheckboxIndeterminate"
14
+ :dense="$attrs.dense!==false"
15
+ :ripple="false"
16
+ v-bind="{...$attrs, ...attrs}"
17
+ v-on="{...$listeners, ...on}"
18
+ @update:error="setError"
19
+ >
20
+ <template #label>
21
+ <VcsLabel :html-for="$attrs.id" :dense="!!$attrs.dense">
22
+ {{ $attrs.label }}
23
+ </VcsLabel>
24
+ </template>
25
+ </v-checkbox>
26
+ </span>
27
+ </template>
28
+ </VcsTooltip>
29
+ </template>
30
+ <style lang="scss" scoped>
31
+ .v-input--selection-controls {
32
+ margin: 0;
33
+ padding: 0;
34
+ }
35
+ </style>
36
+ <script>
37
+ import VcsLabel from './VcsLabel.vue';
38
+ import VcsTooltip from '../notification/VcsTooltip.vue';
39
+ import validate from '../notification/validation.js';
40
+
41
+ /**
42
+ * @description Stylized wrapper around {@link https://vuetifyjs.com/en/api/v-checkbox/ |vuetify checkbox}.
43
+ * Provides two height options depending on "dense" property:
44
+ * - if dense is set true (default), height is 24 px
45
+ * - if dense is set false, height is 32 px
46
+ * Provides VcsTooltip to show error messages
47
+ * @vue-prop {('bottom' | 'left' | 'top' | 'right')} [tooltipPosition='right'] - Position of the error tooltip.
48
+ */
49
+ export default {
50
+ name: 'VcsCheckbox',
51
+ components: { VcsTooltip, VcsLabel },
52
+ props: {
53
+ tooltipPosition: {
54
+ type: String,
55
+ default: 'right',
56
+ },
57
+ },
58
+ data() {
59
+ return {
60
+ errorMessage: '',
61
+ };
62
+ },
63
+ methods: {
64
+ setError() {
65
+ const rules = [...this.$attrs.rules].concat(this.$attrs.errorMessages);
66
+ this.errorMessage = validate(rules, this.$attrs.value).join('\n');
67
+ },
68
+ },
69
+ model: {
70
+ event: 'change',
71
+ },
72
+ };
73
+ </script>
@@ -0,0 +1,81 @@
1
+ <template>
2
+ <v-color-picker
3
+ ref="picker"
4
+ @input="(e) => sub$.next(e)"
5
+ :value="value"
6
+ class="caption"
7
+ v-bind="props"
8
+ />
9
+ </template>
10
+
11
+ <style lang="scss" scoped>
12
+ ::v-deep {
13
+ .v-color-picker__controls {
14
+ padding: 8px;
15
+ }
16
+
17
+ .v-color-picker__input input {
18
+ margin: 0;
19
+ }
20
+
21
+ .v-color-picker__edit {
22
+ margin-top: 12px;
23
+ }
24
+ }
25
+ </style>
26
+
27
+ <script>
28
+ import {
29
+ onMounted,
30
+ onUnmounted,
31
+ } from '@vue/composition-api';
32
+ import { Subject } from 'rxjs';
33
+ import { debounceTime, takeUntil } from 'rxjs/operators';
34
+
35
+ /**
36
+ * @description
37
+ * Stylized wrapper around vuetify Color Picker
38
+ */
39
+ export default {
40
+ name: 'VcsColorPicker',
41
+ props: {
42
+ width: {
43
+ type: Number,
44
+ default: 200,
45
+ },
46
+ mode: {
47
+ type: String,
48
+ default: 'hexa',
49
+ },
50
+ dotSize: {
51
+ type: Number,
52
+ default: 12,
53
+ },
54
+ value: {
55
+ type: String,
56
+ default: '#000000',
57
+ },
58
+ },
59
+ setup(props, context) {
60
+ const destroy$ = new Subject();
61
+ const sub$ = new Subject();
62
+
63
+ onMounted(() => {
64
+ sub$.pipe(debounceTime(330), takeUntil(destroy$)).subscribe((color) => {
65
+ // this.$vuetify.theme.themes.light.primary = color;
66
+ context.emit('input', color);
67
+ });
68
+ });
69
+
70
+ onUnmounted(() => {
71
+ destroy$.next();
72
+ destroy$.unsubscribe();
73
+ });
74
+
75
+ return {
76
+ props,
77
+ sub$,
78
+ };
79
+ },
80
+ };
81
+ </script>
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <section class="vcs-form-section">
3
+ <slot name="title">
4
+ <article class="pa-2 accent">
5
+ <div class="form-section-header d-flex justify-space-between align-center">
6
+ <strong class="caption">{{ title }}</strong>
7
+ <VcsActionButtonList
8
+ :actions="titleActions"
9
+ small
10
+ />
11
+ </div>
12
+ </article>
13
+ </slot>
14
+ <article class="section-content">
15
+ <slot />
16
+ </article>
17
+ </section>
18
+ </template>
19
+
20
+
21
+ <script>
22
+ import VcsActionButtonList from '../buttons/VcsActionButtonList.vue';
23
+
24
+ /**
25
+ * @description
26
+ * Stylized form section with action buttons
27
+ * @vue-data {slot} [#title] - slot to override form section header
28
+ * @vue-data {slot} [#default] - slot with the section content
29
+ * @vue-prop {string} title - Title to be displayed
30
+ * @vue-prop {Array<VcsAction>} titleActions - Icons to be displayed on the right side
31
+ */
32
+ export default {
33
+ name: 'VcsFormSection',
34
+ components: { VcsActionButtonList },
35
+ props: {
36
+ title: {
37
+ type: String,
38
+ default: undefined,
39
+ },
40
+ titleActions: {
41
+ type: Array,
42
+ default: () => ([]),
43
+ },
44
+ },
45
+ };
46
+ </script>
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <label :htmlFor="htmlFor" class="vcs-label" :class="{'vcs-label-dense': dense}">
3
+ <slot />
4
+ </label>
5
+ </template>
6
+ <style lang="scss" scoped>
7
+ @import "../../styles/vcsGrid.scss";
8
+ @import "../../styles/vcsFont";
9
+ .vcs-label {
10
+ font-size: $base-font-size;
11
+ line-height: $line-height-base;
12
+ }
13
+ .vcs-label-dense {
14
+ line-height: $line-height-dense;
15
+ }
16
+ </style>
17
+ <script>
18
+
19
+ /**
20
+ * @description Stylized wrapper around {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label |label label}.
21
+ * pass the label text as innerHtml
22
+ * @vue-prop {string} htmlFor - an id reference the label is meant for
23
+ * @vue-prop {boolean} [dense=true] - default line height is 32px (dense). If set false, height is 40px.
24
+ */
25
+ export default {
26
+ name: 'VcsLabel',
27
+ props: {
28
+ htmlFor: {
29
+ type: String,
30
+ default: undefined,
31
+ },
32
+ dense: {
33
+ type: Boolean,
34
+ default: true,
35
+ },
36
+ },
37
+ };
38
+ </script>
@@ -0,0 +1,97 @@
1
+ <template>
2
+ <div
3
+ @mouseover="hover = true"
4
+ @mouseleave="hover = false"
5
+ >
6
+ <VcsTooltip
7
+ :tooltip-position="tooltipPosition"
8
+ :tooltip="errorMessage"
9
+ color="error"
10
+ >
11
+ <template #activator="{ on, attrs }">
12
+ <span v-on="on">
13
+ <v-select
14
+ append-icon="mdi-chevron-down"
15
+ hide-details
16
+ flat
17
+ :outlined="isOutlined"
18
+ :dense="isDense"
19
+ :height="isDense ? 24 : 32"
20
+ :class="$attrs.color === 'primary' ? 'primary--select' : ''"
21
+ v-bind="{...$attrs, ...attrs}"
22
+ v-on="{...$listeners, ...on}"
23
+ @update:error="setError"
24
+ />
25
+ </span>
26
+ </template>
27
+ </VcsTooltip>
28
+ </div>
29
+ </template>
30
+ <style lang="scss" scoped>
31
+ .v-text-field {
32
+ padding: 0;
33
+ margin: 0;
34
+ }
35
+
36
+ .vcs-select-hover{
37
+ color: var(--v-primary-base) !important;
38
+ }
39
+
40
+ .primary--select {
41
+ ::v-deep {
42
+ .v-select__selection,
43
+ .v-select__selection--comma,
44
+ .v-select.v-text-field input {
45
+ color: var(--v-primary-base);
46
+ }
47
+ }
48
+ }
49
+ </style>
50
+ <script>
51
+
52
+ import VcsTooltip from '../notification/VcsTooltip.vue';
53
+ import validate from '../notification/validation.js';
54
+
55
+ /**
56
+ * @description Stylized wrapper around {@link https://vuetifyjs.com/en/api/v-select/ |vuetify select}.
57
+ * Provides two height options depending on "dense" property:
58
+ * - if dense is set true (default), height is 24 px
59
+ * - if dense is set false, height is 32 px
60
+ * Provides VcsTooltip to show error messages
61
+ * @vue-prop {('bottom' | 'left' | 'top' | 'right')} [tooltipPosition='right'] - Position of the error tooltip.
62
+ * @vue-computed {boolean} isDense - Whether size of select is dense.
63
+ * @vue-computed {boolean} isOutlined - Select is outlined on either hover, focus or error, if not disabled.
64
+ */
65
+ export default {
66
+ name: 'VcsSelect',
67
+ components: { VcsTooltip },
68
+ props: {
69
+ tooltipPosition: {
70
+ type: String,
71
+ default: 'right',
72
+ },
73
+ },
74
+ data() {
75
+ return {
76
+ hover: false,
77
+ errorMessage: '',
78
+ };
79
+ },
80
+ computed: {
81
+ isDense() {
82
+ return this.$attrs.dense !== undefined && this.$attrs.dense !== false;
83
+ },
84
+ isOutlined() {
85
+ return (this.hover || this.errorMessage.length > 0) &&
86
+ !(this.$attrs.disabled || this.$attrs.disabled === '');
87
+ },
88
+ },
89
+ methods: {
90
+ setError() {
91
+ const rules = [...this.$attrs.rules].concat(this.$attrs.errorMessages);
92
+ this.errorMessage = validate(rules, this.$attrs.value).join('\n');
93
+ },
94
+ },
95
+ };
96
+ </script>
97
+
@@ -0,0 +1,130 @@
1
+ <template>
2
+ <div
3
+ @mouseover="hover = true"
4
+ @mouseleave="hover = false"
5
+ >
6
+ <VcsTooltip
7
+ :tooltip-position="tooltipPosition"
8
+ :tooltip="errorMessage"
9
+ :value="(hover || focus) && isError"
10
+ color="error"
11
+ :max-width="200"
12
+ >
13
+ <template #activator="{ attrs }">
14
+ <v-textarea
15
+ ref="textAreaRef"
16
+ hide-details
17
+ :dense="isDense"
18
+ :clearable="isClearable"
19
+ @focus="focus = true"
20
+ @blur="focus = neverBlurred = false"
21
+ @input="firstInput = true"
22
+ :outlined="isOutlined"
23
+ v-bind="{...$attrs, ...attrs}"
24
+ v-on="{...$listeners}"
25
+ :rows="$attrs.rows || (isDense ? 3 : 5)"
26
+ class="ma-0 pb-1 pt-1 primary--placeholder"
27
+ :class="$attrs.color === 'primary' ? 'primary--textarea' : ''"
28
+ />
29
+ </template>
30
+ </VcsTooltip>
31
+ </div>
32
+ </template>
33
+
34
+ <style lang="scss" scoped>
35
+ .primary--placeholder {
36
+ ::v-deep {
37
+ textarea::placeholder {
38
+ color: var(--v-primary-base);
39
+ font-style: italic;
40
+ opacity: 1;
41
+ }
42
+ }
43
+ }
44
+ .primary--textarea {
45
+ ::v-deep {
46
+ textarea {
47
+ color: var(--v-primary-base);
48
+ }
49
+ }
50
+ }
51
+ </style>
52
+
53
+ <script>
54
+ import VcsTooltip from '../notification/VcsTooltip.vue';
55
+
56
+ /**
57
+ * @description extends API of {@link https://vuetifyjs.com/en/api/v-textarea/|vuetify v-textarea}.
58
+ * Provides two default height options depending on "dense" property:
59
+ * - if dense is set true (default), height is 72 px (3 rows each 24 px)
60
+ * - if dense is set false, height is 120 px (5 rows each 24 px)
61
+ * Default for number of rows can be overwritten using the vuetify API.
62
+ * Provides VcsTooltip to
63
+ * - show error messages on focus
64
+ * - show tooltips, if supplied, when hovered over append-icon
65
+ * @vue-prop {('bottom' | 'left' | 'top' | 'right')} [tooltipPosition='right'] - Position of the error tooltip.
66
+ * @vue-computed {boolean} isClearable - Whether textarea is isClearable. Makes sure icon is only shown on focus, hover or error.
67
+ * @vue-computed {boolean} isDense - Whether size of textarea is dense.
68
+ * @vue-computed {boolean} isError - Whether errorBucket is not empty and textarea was focused at least once.
69
+ * @vue-computed {boolean} isOutlined - Textarea is outlined on either hover, focus or error, if not disabled.
70
+ * @vue-computed {Array<string>} joinedErrorBucket - errorBucket + errorMessages of child v-text-field.
71
+ */
72
+ export default {
73
+ name: 'VcsTextArea',
74
+ components: {
75
+ VcsTooltip,
76
+ },
77
+ props: {
78
+ tooltipPosition: {
79
+ type: String,
80
+ default: 'right',
81
+ },
82
+ },
83
+ data() {
84
+ return {
85
+ hover: false,
86
+ focus: false,
87
+ firstInput: false,
88
+ neverBlurred: true,
89
+ isMounted: false,
90
+ errorMessage: '',
91
+ };
92
+ },
93
+ computed: {
94
+ isClearable() {
95
+ return (this.$attrs.clearable !== undefined && this.$attrs.clearable !== false) &&
96
+ (this.hover || this.focus || this.isError);
97
+ },
98
+ isDense() {
99
+ return this.$attrs.dense !== undefined && this.$attrs.dense !== false;
100
+ },
101
+ isError() {
102
+ return this.joinedErrorBucket.length > 0 && (this.firstInput || !this.neverBlurred);
103
+ },
104
+ isOutlined() {
105
+ return (this.hover || this.focus || this.isError) && !(this.$attrs.disabled || this.$attrs.disabled === '');
106
+ },
107
+ joinedErrorBucket() {
108
+ if (!this.isMounted) {
109
+ return false;
110
+ } else {
111
+ return this.$refs.textAreaRef.errorBucket.concat(this.$refs.textAreaRef.errorMessages).join('\n');
112
+ }
113
+ },
114
+ },
115
+ watch: {
116
+ joinedErrorBucket(newValue, oldValue) {
117
+ if (oldValue && !newValue) {
118
+ setTimeout(() => {
119
+ this.errorMessage = newValue;
120
+ }, 200);
121
+ } else {
122
+ this.errorMessage = newValue;
123
+ }
124
+ },
125
+ },
126
+ mounted() {
127
+ this.isMounted = true;
128
+ },
129
+ };
130
+ </script>