@eturnity/eturnity_reusable_components 6.43.9-EPDM-6751.5 → 6.43.9-EPDM-6751.6
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/package.json
CHANGED
@@ -104,6 +104,7 @@
|
|
104
104
|
:selectedValue="selectedValue"
|
105
105
|
@option-selected="optionSelected"
|
106
106
|
@option-hovered="optionHovered"
|
107
|
+
@mouseleave="optionLeave"
|
107
108
|
>
|
108
109
|
<slot name="dropdown"></slot>
|
109
110
|
</selectDropdown>
|
@@ -335,6 +336,10 @@ export default {
|
|
335
336
|
required: false,
|
336
337
|
default: false
|
337
338
|
},
|
339
|
+
dropdownAutoClose: {
|
340
|
+
required: false,
|
341
|
+
default: true
|
342
|
+
},
|
338
343
|
alignItems: {
|
339
344
|
required: false,
|
340
345
|
default: 'horizontal'
|
@@ -460,6 +465,11 @@ export default {
|
|
460
465
|
this.blur()
|
461
466
|
}
|
462
467
|
},
|
468
|
+
optionLeave() {
|
469
|
+
if(this.dropdownAutoClose) {
|
470
|
+
this.isDropdownOpen = false
|
471
|
+
}
|
472
|
+
},
|
463
473
|
searchChange(value) {
|
464
474
|
this.textSearch = value
|
465
475
|
this.$emit('search-change', value)
|
@@ -1,64 +1,65 @@
|
|
1
1
|
<template>
|
2
|
-
<page-container @click="toggleButton()">
|
2
|
+
<page-container @click="toggleButton()" ref="pageContainer" :activated="isOpen">
|
3
3
|
<button-container ref="dropdownItem">
|
4
4
|
<dot-item />
|
5
5
|
<dot-item />
|
6
6
|
<dot-item />
|
7
7
|
</button-container>
|
8
8
|
<dropdown-container
|
9
|
-
v-if="isOpen"
|
10
9
|
@click.stop
|
11
10
|
:containerWidth="childOpen ? 440 : 240"
|
12
11
|
ref="dropdownContainer"
|
13
12
|
>
|
14
|
-
<
|
15
|
-
<
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
13
|
+
<template v-if="isOpen">
|
14
|
+
<loading-container v-if="isLoading">
|
15
|
+
<spinner />
|
16
|
+
</loading-container>
|
17
|
+
<children-container
|
18
|
+
class="child"
|
19
|
+
:isOpen="hoverItem !== null"
|
20
|
+
v-if="hoverItem !== null && !isLoading"
|
21
|
+
>
|
22
|
+
<option-child
|
23
|
+
v-for="child in childOpen"
|
24
|
+
:key="child.value"
|
25
|
+
@click.stop="
|
26
26
|
onSelect({
|
27
27
|
item: child,
|
28
28
|
hasChildren: hasChildren(child)
|
29
29
|
})
|
30
30
|
"
|
31
|
-
|
31
|
+
@keyup.enter.stop="
|
32
32
|
onSelect({
|
33
33
|
item: child,
|
34
34
|
hasChildren: hasChildren(child)
|
35
35
|
})
|
36
36
|
"
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
>
|
38
|
+
{{ child.name }}
|
39
|
+
</option-child>
|
40
|
+
</children-container>
|
41
|
+
<options-container v-if="!isLoading">
|
42
|
+
<option-item
|
43
|
+
v-for="(item, index) in options"
|
44
|
+
:key="item.value"
|
45
|
+
tabindex="0"
|
46
|
+
@click.stop="onSelect({ item: item, hasChildren: hasChildren(item) })"
|
47
|
+
@keyup.enter="
|
48
48
|
onSelect({ item: item, hasChildren: hasChildren(item) })
|
49
49
|
"
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
@mouseover="onItemHover({ index, item })"
|
51
|
+
:isDisabled="item.disabled"
|
52
|
+
>
|
53
|
+
<arrow-left
|
54
|
+
:hasChildren="hasChildren(item)"
|
55
|
+
v-if="hasChildren(item)"
|
56
|
+
/>
|
57
|
+
<span>
|
58
58
|
{{ item.name }}
|
59
59
|
</span>
|
60
|
-
|
61
|
-
|
60
|
+
</option-item>
|
61
|
+
</options-container>
|
62
|
+
</template>
|
62
63
|
</dropdown-container>
|
63
64
|
</page-container>
|
64
65
|
</template>
|
@@ -122,17 +123,20 @@
|
|
122
123
|
import styled from 'vue-styled-components'
|
123
124
|
import Spinner from '../spinner'
|
124
125
|
|
125
|
-
const
|
126
|
+
const PageContainerAttrs = {
|
127
|
+
activated: Boolean
|
128
|
+
}
|
129
|
+
const PageContainer = styled('div', PageContainerAttrs)`
|
126
130
|
display: grid;
|
127
131
|
align-items: center;
|
128
132
|
justify-items: center;
|
129
133
|
width: 30px;
|
130
134
|
height: 30px;
|
131
|
-
|
135
|
+
border-radius: 4px;
|
136
|
+
background-color: ${(props) => props.activated ? props.theme.colors.grey5 : ''};
|
132
137
|
|
133
138
|
&:hover {
|
134
139
|
background-color: ${(props) => props.theme.colors.grey5};
|
135
|
-
border-radius: 4px;
|
136
140
|
}
|
137
141
|
`
|
138
142
|
|
@@ -162,10 +166,6 @@ const dropdownAttrs = {
|
|
162
166
|
}
|
163
167
|
const DropdownContainer = styled('div', dropdownAttrs)`
|
164
168
|
z-index: 99;
|
165
|
-
height: 200px;
|
166
|
-
top: 0;
|
167
|
-
right: 27px;
|
168
|
-
|
169
169
|
position: absolute;
|
170
170
|
display: grid;
|
171
171
|
grid-template-columns: auto auto;
|
@@ -175,8 +175,8 @@ const LoadingContainer = styled.div`
|
|
175
175
|
border: 1px solid ${(props) => props.theme.colors.grey3};
|
176
176
|
display: grid;
|
177
177
|
grid-template-columns: 1fr;
|
178
|
-
min-width:
|
179
|
-
height:
|
178
|
+
min-width: 100px;
|
179
|
+
height: 100px;
|
180
180
|
align-items: center;
|
181
181
|
justify-items: center;
|
182
182
|
background: #fff;
|
@@ -257,6 +257,9 @@ const ChildrenContainer = styled('div', childAttrs)`
|
|
257
257
|
height: max-content;
|
258
258
|
max-height: 200px;
|
259
259
|
overflow: auto;
|
260
|
+
position: absolute;
|
261
|
+
top: 0;
|
262
|
+
right: 100%;
|
260
263
|
`
|
261
264
|
|
262
265
|
export default {
|
@@ -296,11 +299,65 @@ export default {
|
|
296
299
|
this.isOpen = !this.isOpen
|
297
300
|
|
298
301
|
if (this.isOpen) {
|
302
|
+
this.setContextMenuPosition()
|
303
|
+
window.addEventListener('resize', this.toggleButton)
|
299
304
|
document.addEventListener('click', this.clickOutside)
|
300
305
|
} else {
|
306
|
+
window.removeEventListener('resize', this.toggleButton)
|
301
307
|
document.removeEventListener('click', this.clickOutside)
|
302
308
|
}
|
303
309
|
},
|
310
|
+
setContextMenuPosition() {
|
311
|
+
const contextMenu = this.$refs.dropdownContainer.$el
|
312
|
+
const button = this.$refs.pageContainer.$el
|
313
|
+
const rectButton = button.getBoundingClientRect()
|
314
|
+
const relativeParent = this.findRelativeParent(contextMenu)
|
315
|
+
const rectRelativeParent = relativeParent.getBoundingClientRect()
|
316
|
+
|
317
|
+
const positionArray = this.determineElementQuarter(button, rectButton)
|
318
|
+
contextMenu.style.transform = ''
|
319
|
+
if (positionArray.includes('left')) {
|
320
|
+
contextMenu.style.left = (rectButton.right - rectRelativeParent.left + 5) + 'px'
|
321
|
+
} else {
|
322
|
+
contextMenu.style.left = (rectButton.left - rectRelativeParent.left - 5) + 'px'
|
323
|
+
contextMenu.style.transform = 'translateX(-100%)'
|
324
|
+
}
|
325
|
+
if (positionArray.includes('top')) {
|
326
|
+
contextMenu.style.top = (rectButton.top - rectRelativeParent.top) + 'px'
|
327
|
+
} else {
|
328
|
+
contextMenu.style.top = (rectButton.bottom - rectRelativeParent.top) + 'px'
|
329
|
+
contextMenu.style.transform += ' translateY(-100%)'
|
330
|
+
}
|
331
|
+
},
|
332
|
+
findRelativeParent(element) {
|
333
|
+
while (element.parentElement) {
|
334
|
+
if (window.getComputedStyle(element.parentElement).position === 'relative') {
|
335
|
+
return element.parentElement
|
336
|
+
}
|
337
|
+
element = element.parentElement
|
338
|
+
}
|
339
|
+
return null
|
340
|
+
},
|
341
|
+
determineElementQuarter(element, rect) {
|
342
|
+
const viewportWidth = window.innerWidth
|
343
|
+
const viewportHeight = window.innerHeight
|
344
|
+
|
345
|
+
const horizontalMidpoint = viewportWidth / 2
|
346
|
+
const verticalMidpoint = viewportHeight / 2
|
347
|
+
|
348
|
+
const isLeft = rect.left + rect.width / 2 < horizontalMidpoint
|
349
|
+
const isTop = rect.top + rect.height / 2 < verticalMidpoint
|
350
|
+
|
351
|
+
if (isLeft && isTop) {
|
352
|
+
return ['left', 'top']
|
353
|
+
} else if (isLeft && !isTop) {
|
354
|
+
return ['left', 'bottom']
|
355
|
+
} else if (!isLeft && isTop) {
|
356
|
+
return ['right', 'top']
|
357
|
+
} else {
|
358
|
+
return ['right', 'bottom']
|
359
|
+
}
|
360
|
+
},
|
304
361
|
hasChildren(item) {
|
305
362
|
return !!item.children && !!item.children.length
|
306
363
|
},
|