@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.
- package/README.md +69 -22
- package/build/build.js +0 -3
- package/build/buildHelpers.js +0 -1
- package/build/commonViteConfig.js +1 -1
- package/config/dev.config.json +4 -4
- package/dist/assets/{cesium.6b5bb6.js → cesium.4e40f4.js} +0 -0
- package/dist/assets/cesium.js +1 -1
- package/dist/assets/core.edcf5e.js +4 -0
- package/dist/assets/core.js +1 -1
- package/dist/assets/{index.0be2842f.js → index.889d0f3a.js} +1 -1
- package/dist/assets/{ol.0561aa.js → ol.246fd4.js} +0 -0
- package/dist/assets/ol.js +1 -1
- package/dist/assets/ui.df4f6d.css +1 -0
- package/dist/assets/ui.df4f6d.js +43 -0
- package/dist/assets/ui.js +1 -1
- package/dist/assets/{vue-composition-api.f926fa.js → vue-composition-api.a520f3.js} +1 -1
- package/dist/assets/vue-composition-api.js +2 -2
- package/dist/assets/{vue.ddcb6b.js → vue.2cee44.js} +0 -0
- package/dist/assets/vue.js +1 -1
- package/dist/assets/{vuetify.d21163.css → vuetify.cc817b.css} +0 -0
- package/dist/assets/{vuetify.d21163.js → vuetify.cc817b.js} +1 -1
- package/dist/assets/vuetify.js +2 -2
- package/dist/index.html +1 -1
- package/index.js +39 -1
- package/package.json +2 -3
- package/plugins/@vcmap/pluginExample/index.js +5 -5
- package/plugins/@vcmap/pluginExample/pluginExampleComponent.vue +1 -1
- package/plugins/@vcmap/project-selector/ContextsListComponent.vue +1 -1
- package/plugins/@vcmap/project-selector/index.js +5 -5
- package/plugins/@vcmap/project-selector/package.json +1 -2
- package/plugins/@vcmap/theme-changer/index.js +6 -6
- package/plugins/buttonExamples/ButtonExamples.vue +1 -1
- package/plugins/buttonExamples/index.js +5 -4
- package/plugins/categoryTest/Categories.vue +1 -1
- package/plugins/categoryTest/Category.vue +1 -1
- package/plugins/categoryTest/index.js +5 -5
- package/plugins/example/index.js +33 -14
- package/plugins/test/allIconsComponent.vue +34 -0
- package/plugins/test/editor.vue +1 -1
- package/plugins/test/index.js +40 -17
- package/plugins/test/toolbox-data.js +106 -26
- package/plugins/test/windowManagerExample.vue +1 -2
- package/src/actions/actionHelper.js +2 -1
- package/src/actions/styleSelector.vue +1 -1
- package/src/application/Navbar.vue +18 -6
- package/src/application/VcsApp.vue +34 -28
- package/src/assets/logo-mobile.svg +9 -0
- package/src/assets/logo.svg +23 -23
- package/src/components/buttons/VcsActionButtonList.vue +99 -0
- package/src/components/buttons/VcsButton.vue +201 -0
- package/src/components/form-inputs-controls/VcsCheckbox.vue +73 -0
- package/src/components/form-inputs-controls/VcsColorPicker.vue +81 -0
- package/src/components/form-inputs-controls/VcsFormSection.vue +46 -0
- package/src/components/form-inputs-controls/VcsLabel.vue +38 -0
- package/src/components/form-inputs-controls/VcsSelect.vue +97 -0
- package/src/components/form-inputs-controls/VcsTextArea.vue +130 -0
- package/src/components/form-inputs-controls/VcsTextField.vue +129 -0
- package/src/components/form-output/VcsFormattedNumber.vue +103 -0
- package/src/components/lists/VcsActionList.vue +100 -0
- package/src/components/lists/VcsTreeview.vue +109 -0
- package/src/components/lists/VcsTreeviewLeaf.vue +105 -0
- package/src/components/lists/VcsTreeviewSearchbar.vue +156 -0
- package/src/components/notification/VcsBadge.vue +27 -0
- package/src/components/notification/VcsTooltip.vue +154 -0
- package/src/components/notification/validation.js +19 -0
- package/src/contentTree/LayerTree.vue +1 -1
- package/src/contentTree/contentTreeCollection.js +6 -2
- package/src/icons/+all.js +359 -0
- package/src/icons/2DAreaIcon.vue +21 -0
- package/src/icons/2DDistanceIcon.vue +18 -0
- package/src/icons/3DAreaIcon.vue +21 -0
- package/src/icons/3DDistanceIcon.vue +18 -0
- package/src/icons/3DHeightIcon.vue +18 -0
- package/src/icons/AngleIcon.vue +8 -0
- package/src/icons/AssociationsIcon.vue +34 -0
- package/src/icons/AxisIcon.vue +10 -0
- package/src/icons/BoundingBoxIcon.vue +15 -0
- package/src/icons/CheckboxCheckedIcon.vue +16 -0
- package/src/icons/CheckboxIcon.vue +23 -0
- package/src/icons/CheckboxIndeterminateIcon.vue +24 -0
- package/src/icons/CircleIcon.vue +10 -0
- package/src/icons/ColorSwatchIcon.vue +17 -0
- package/src/icons/CommentIcon.vue +19 -0
- package/src/icons/CompassIcon.vue +8 -0
- package/src/icons/ComponentsIcon.vue +7 -0
- package/src/icons/ConeIcon.vue +11 -0
- package/src/icons/DimensionsHouseIcon.vue +14 -0
- package/src/icons/ElevationProfileIcon.vue +111 -0
- package/src/icons/ExportAreaIcon.vue +7 -0
- package/src/icons/ExportFlightIcon.vue +7 -0
- package/src/icons/ExportIcon.vue +8 -0
- package/src/icons/ExternalLinkIcon.vue +10 -0
- package/src/icons/EyeIcon.vue +7 -0
- package/src/icons/FastForwardIcon.vue +7 -0
- package/src/icons/FilterIcon.vue +8 -0
- package/src/icons/GlobeNatureIcon.vue +14 -0
- package/src/icons/HealthCareIndustriesIcon.vue +118 -0
- package/src/icons/HelpIcon.vue +7 -0
- package/src/icons/HomePointIcon.vue +8 -0
- package/src/icons/HospitalsIcon.vue +237 -0
- package/src/icons/HouseIcon.vue +25 -0
- package/src/icons/ImportIcon.vue +8 -0
- package/src/icons/InfoIcon.vue +10 -0
- package/src/icons/KebabIcon.vue +36 -0
- package/src/icons/LabelIcon.vue +7 -0
- package/src/icons/LayersIcon.vue +26 -0
- package/src/icons/LegendIcon.vue +65 -0
- package/src/icons/LineIcon.vue +7 -0
- package/src/icons/LinkIcon.vue +7 -0
- package/src/icons/MapIcon.vue +8 -0
- package/src/icons/MenuIcon.vue +34 -0
- package/src/icons/MinusIcon.vue +8 -0
- package/src/icons/ObjectAttributeIcon.vue +18 -0
- package/src/icons/ObjectSelectIcon.vue +8 -0
- package/src/icons/ObliqueViewIcon.vue +13 -0
- package/src/icons/PdfIcon.vue +10 -0
- package/src/icons/PedestrianIcon.vue +8 -0
- package/src/icons/PenIcon.vue +14 -0
- package/src/icons/PlayCircleIcon.vue +10 -0
- package/src/icons/PlusIcon.vue +9 -0
- package/src/icons/PoiIcon.vue +7 -0
- package/src/icons/PointSelectIcon.vue +7 -0
- package/src/icons/PolygonIcon.vue +38 -0
- package/src/icons/PresentationModeIcon.vue +7 -0
- package/src/icons/ProgressIcon.vue +24 -0
- package/src/icons/QueryIcon.vue +15 -0
- package/src/icons/RectangleIcon.vue +9 -0
- package/src/icons/ReturnIcon.vue +7 -0
- package/src/icons/RewindIcon.vue +6 -0
- package/src/icons/SearchIcon.vue +8 -0
- package/src/icons/ShadowIcon.vue +9 -0
- package/src/icons/ShapesIcon.vue +28 -0
- package/src/icons/ShareIcon.vue +22 -0
- package/src/icons/SimpleCircleFilledIcon.vue +15 -0
- package/src/icons/SimpleCircleHalfFilledIcon.vue +12 -0
- package/src/icons/SimpleCircleOutlinedIcon.vue +15 -0
- package/src/icons/SkipNextIcon.vue +7 -0
- package/src/icons/SkipPreviousIcon.vue +9 -0
- package/src/icons/SplitViewIcon.vue +19 -0
- package/src/icons/TextStyleIcon.vue +14 -0
- package/src/icons/ThreeDimensionsIcon.vue +7 -0
- package/src/icons/ToolsIcon.vue +35 -0
- package/src/icons/TouchIcon.vue +8 -0
- package/src/icons/TrashCanIcon.vue +7 -0
- package/src/icons/TriangleIcon.vue +15 -0
- package/src/icons/TwoDimensionsIcon.vue +8 -0
- package/src/icons/UploadIcon.vue +14 -0
- package/src/icons/VideoRecorderIcon.vue +14 -0
- package/src/icons/WalkingIcon.vue +7 -0
- package/src/icons/WallIcon.vue +14 -0
- package/src/manager/buttonManager.js +5 -53
- package/src/manager/navbarManager.js +81 -0
- package/src/manager/toolbox/ToolboxGroupComponent.vue +128 -0
- package/src/manager/toolbox/ToolboxManager.vue +119 -76
- package/src/manager/toolbox/toolboxManager.js +204 -0
- package/src/manager/window/WindowComponentHeader.vue +1 -1
- package/src/manager/window/WindowManager.vue +18 -1
- package/src/manager/window/windowManager.js +3 -5
- package/src/navigation/mapNavigation.vue +9 -5
- package/src/navigation/orientationToolsButton.vue +1 -1
- package/src/navigation/tiltSlider.vue +1 -1
- package/src/styles/_theming.scss +10 -0
- package/src/styles/main.scss +3 -0
- package/src/styles/variables.scss +70 -0
- package/src/styles/vcsFont.scss +5 -0
- package/src/styles/vcsGrid.scss +4 -0
- package/src/vcsUiApp.js +4 -3
- package/src/vuePlugins/vuetify.js +1 -1
- package/dist/assets/core.98f9bb.js +0 -4
- package/dist/assets/ui.b7c1e3.css +0 -1
- package/dist/assets/ui.b7c1e3.js +0 -39
- package/dist/assets/uicomponents.682c5f.css +0 -1
- package/dist/assets/uicomponents.682c5f.js +0 -32
- package/dist/assets/uicomponents.js +0 -1
- package/lib/uicomponents.js +0 -1
- package/src/manager/toolbox/ToolboxMultiSelectButton.vue +0 -96
- package/src/manager/toolbox/ToolboxSingleSelectButton.vue +0 -98
- 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>
|