js-kompo-utils 1.0.19 → 1.0.21
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/components/VlDropdown.vue +13 -3
- package/components/VlSelect.vue +120 -0
- package/package.json +1 -1
|
@@ -50,6 +50,7 @@ export default {
|
|
|
50
50
|
menuLeft: -9999,
|
|
51
51
|
menuRight: null,
|
|
52
52
|
inModal: false,
|
|
53
|
+
autoFlipUp: false,
|
|
53
54
|
}
|
|
54
55
|
},
|
|
55
56
|
watch:{
|
|
@@ -81,9 +82,12 @@ export default {
|
|
|
81
82
|
isRightAligned() {
|
|
82
83
|
return this.dropdownPosition.includes('Right')
|
|
83
84
|
},
|
|
84
|
-
|
|
85
|
+
forcedUpward() {
|
|
85
86
|
return this.dropdownPosition.includes('Up')
|
|
86
87
|
},
|
|
88
|
+
isUpward() {
|
|
89
|
+
return this.forcedUpward || this.autoFlipUp
|
|
90
|
+
},
|
|
87
91
|
menuPositionStyle() {
|
|
88
92
|
const style = {
|
|
89
93
|
position: 'fixed',
|
|
@@ -155,7 +159,7 @@ export default {
|
|
|
155
159
|
const root = this.$refs.dropdownRoot
|
|
156
160
|
if (!menu) return
|
|
157
161
|
|
|
158
|
-
this.inModal = !!(root && root.closest('.kompoModal'))
|
|
162
|
+
this.inModal = !!(root && root.closest('.kompoModal, .kompoDrawer, .vl-sidebar-l'))
|
|
159
163
|
|
|
160
164
|
// Transfer scroll styles from root before teleporting
|
|
161
165
|
if (root && root.classList.contains('dropdown-with-scroll')) {
|
|
@@ -206,9 +210,15 @@ export default {
|
|
|
206
210
|
if (!root) return
|
|
207
211
|
|
|
208
212
|
const rect = root.getBoundingClientRect()
|
|
213
|
+
const menuHeight = menu ? menu.offsetHeight : 0
|
|
214
|
+
|
|
215
|
+
if (!this.forcedUpward) {
|
|
216
|
+
const spaceBelow = window.innerHeight - rect.bottom
|
|
217
|
+
const spaceAbove = rect.top
|
|
218
|
+
this.autoFlipUp = spaceBelow < menuHeight && spaceAbove > spaceBelow
|
|
219
|
+
}
|
|
209
220
|
|
|
210
221
|
if (this.isUpward) {
|
|
211
|
-
const menuHeight = menu ? menu.offsetHeight : 0
|
|
212
222
|
this.menuTop = rect.top - menuHeight
|
|
213
223
|
} else {
|
|
214
224
|
this.menuTop = rect.bottom
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<vl-form-field v-bind="$_wrapperAttributes">
|
|
3
|
+
<vlTaggableInput
|
|
4
|
+
v-click-out="blur"
|
|
5
|
+
v-bind="$_taggableInputAttributes"
|
|
6
|
+
v-on="$_taggableInputEvents">
|
|
7
|
+
<template v-slot:prepend v-if="$_icon">
|
|
8
|
+
<div v-bind="prependIcon" />
|
|
9
|
+
</template>
|
|
10
|
+
<input
|
|
11
|
+
class="vlFormControl"
|
|
12
|
+
v-bind="$_attributes"
|
|
13
|
+
v-on="$_events"
|
|
14
|
+
v-model="inputValue"
|
|
15
|
+
@keydown.enter.prevent="() => {}"
|
|
16
|
+
ref="input"
|
|
17
|
+
type="search"
|
|
18
|
+
autocomplete="off"
|
|
19
|
+
/>
|
|
20
|
+
<template v-slot:append v-if="appendIcon && !$_readOnly">
|
|
21
|
+
<div v-html="appendIcon"/>
|
|
22
|
+
</template>
|
|
23
|
+
</vlTaggableInput>
|
|
24
|
+
<div class="vlOptions"
|
|
25
|
+
:key="optionsKey"
|
|
26
|
+
ref="selectOptions"
|
|
27
|
+
:style="optionsStyle"
|
|
28
|
+
:class="{ 'vlOptionsFlipUp': flipUp }">
|
|
29
|
+
<template v-if="filteredOptions.length">
|
|
30
|
+
<div v-for="(option,key) in filteredOptions" :key="option.value" :ref="key"
|
|
31
|
+
class="vlOption"
|
|
32
|
+
:class="{
|
|
33
|
+
'vlSelected' : isSelected(option),
|
|
34
|
+
'vlHoveredOption' : key == hoveredOption
|
|
35
|
+
}"
|
|
36
|
+
@click.stop="select(option)"
|
|
37
|
+
@mouseover="setHoveredOption(key)">
|
|
38
|
+
<vlCustomLabel :vkompo="option.label" :kompoid="kompoid" />
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
<template v-else>
|
|
42
|
+
<div class="vlOption" v-html="optionsMessage" />
|
|
43
|
+
</template>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<template v-slot:after>
|
|
47
|
+
<slot name="after"/>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
</vl-form-field>
|
|
51
|
+
</template>
|
|
52
|
+
|
|
53
|
+
<script>
|
|
54
|
+
import Select from 'vue-kompo/js/form/form-fields/Select.vue'
|
|
55
|
+
|
|
56
|
+
export default {
|
|
57
|
+
extends: Select,
|
|
58
|
+
data() {
|
|
59
|
+
return {
|
|
60
|
+
flipUp: false,
|
|
61
|
+
overlayStyle: null,
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
computed: {
|
|
65
|
+
isFocused() {
|
|
66
|
+
return this.$_state('focusedField')
|
|
67
|
+
},
|
|
68
|
+
forceUp() {
|
|
69
|
+
return !!this.$_config('openUpward')
|
|
70
|
+
},
|
|
71
|
+
optionsStyle() {
|
|
72
|
+
if (this.overlayStyle) return this.overlayStyle
|
|
73
|
+
if (this.flipUp) {
|
|
74
|
+
return { top: 'auto', bottom: '100%', borderRadius: '5px 5px 0 0' }
|
|
75
|
+
}
|
|
76
|
+
return {}
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
watch: {
|
|
80
|
+
isFocused(focused) {
|
|
81
|
+
if (focused) {
|
|
82
|
+
this.$nextTick(() => this.refresh())
|
|
83
|
+
} else {
|
|
84
|
+
this.flipUp = false
|
|
85
|
+
this.overlayStyle = null
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
filteredOptions() {
|
|
89
|
+
if (this.isFocused) this.$nextTick(() => this.refresh())
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
methods: {
|
|
93
|
+
refresh() {
|
|
94
|
+
const opts = this.$refs.selectOptions
|
|
95
|
+
const anchor = opts && opts.parentElement
|
|
96
|
+
if (!opts || !anchor) return
|
|
97
|
+
|
|
98
|
+
const rect = anchor.getBoundingClientRect()
|
|
99
|
+
const optsHeight = opts.offsetHeight
|
|
100
|
+
const spaceBelow = window.innerHeight - rect.bottom
|
|
101
|
+
const spaceAbove = rect.top
|
|
102
|
+
this.flipUp = this.forceUp || (spaceBelow < optsHeight && spaceAbove > spaceBelow)
|
|
103
|
+
|
|
104
|
+
if (opts.closest('.kompoModal, .kompoDrawer, .vl-sidebar-l')) {
|
|
105
|
+
this.overlayStyle = {
|
|
106
|
+
position: 'fixed',
|
|
107
|
+
left: rect.left + 'px',
|
|
108
|
+
width: rect.width + 'px',
|
|
109
|
+
zIndex: 5001,
|
|
110
|
+
...(this.flipUp
|
|
111
|
+
? { top: 'auto', bottom: (window.innerHeight - rect.top) + 'px', borderRadius: '5px 5px 0 0' }
|
|
112
|
+
: { top: rect.bottom + 'px', bottom: 'auto' }),
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
this.overlayStyle = null
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
}
|
|
120
|
+
</script>
|