@eturnity/eturnity_reusable_components 7.8.6-EPDM-9779.3 → 7.8.6-EPDM-7951.0
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/.storybook/preview.js +1 -1
- package/package.json +18 -23
- package/src/App.vue +2 -2
- package/src/assets/theme.js +0 -2
- package/src/components/addNewButton/index.vue +5 -3
- package/src/components/buttons/buttonIcon/index.vue +1 -1
- package/src/components/buttons/closeButton/index.vue +1 -1
- package/src/components/buttons/mainButton/index.vue +6 -1
- package/src/components/deleteIcon/DeleteIcon.stories.js +7 -7
- package/src/components/deleteIcon/index.vue +25 -21
- package/src/components/draggableInputHandle/index.vue +24 -25
- package/src/components/dropdown/index.vue +129 -110
- package/src/components/errorMessage/index.vue +1 -1
- package/src/components/filter/filterSettings.vue +55 -97
- package/src/components/filter/index.vue +3 -3
- package/src/components/filter/parentDropdown.vue +2 -2
- package/src/components/icon/iconCollection.vue +2 -2
- package/src/components/icon/index.vue +57 -55
- package/src/components/iconWrapper/index.vue +2 -5
- package/src/components/infoCard/index.vue +2 -3
- package/src/components/infoText/index.vue +2 -6
- package/src/components/inputs/checkbox/index.vue +21 -6
- package/src/components/inputs/inputNumber/index.vue +8 -12
- package/src/components/inputs/inputNumberQuestion/index.vue +1 -1
- package/src/components/inputs/inputText/index.vue +3 -8
- package/src/components/inputs/radioButton/index.vue +1 -1
- package/src/components/inputs/searchInput/index.vue +7 -8
- package/src/components/inputs/select/index.vue +213 -72
- package/src/components/inputs/select/option/index.vue +5 -5
- package/src/components/inputs/slider/index.vue +16 -16
- package/src/components/inputs/switchField/index.vue +2 -2
- package/src/components/inputs/textAreaInput/index.vue +1 -1
- package/src/components/inputs/toggle/index.vue +2 -2
- package/src/components/label/index.vue +27 -32
- package/src/components/modals/modal/index.vue +13 -8
- package/src/components/navigationTabs/index.vue +37 -30
- package/src/components/pageSubtitle/index.vue +1 -1
- package/src/components/pageTitle/index.vue +20 -19
- package/src/components/pagination/index.vue +1 -1
- package/src/components/progressBar/index.vue +1 -1
- package/src/components/projectMarker/index.vue +10 -7
- package/src/components/sideMenu/index.vue +1 -1
- package/src/components/spinner/index.vue +6 -11
- package/src/components/tableDropdown/index.vue +21 -26
- package/src/components/tables/mainTable/exampleNested.vue +1 -1
- package/src/components/tables/mainTable/index.vue +2 -1
- package/src/components/tables/viewTable/index.vue +2 -2
- package/src/components/threeDots/index.vue +1 -1
- package/src/components/videoThumbnail/index.vue +95 -100
- package/src/main.js +4 -11
- package/src/assets/svgIcons/expand.svg +0 -1
@@ -34,7 +34,6 @@
|
|
34
34
|
:value="value"
|
35
35
|
@input="onChangeHandler"
|
36
36
|
@blur="onInputBlur"
|
37
|
-
@keyup.enter="onEnterPress"
|
38
37
|
:noBorder="noBorder"
|
39
38
|
:disabled="disabled"
|
40
39
|
:isDisabled="disabled"
|
@@ -67,7 +66,7 @@
|
|
67
66
|
</template>
|
68
67
|
|
69
68
|
<script>
|
70
|
-
import styled from '
|
69
|
+
import styled from 'vue3-styled-components'
|
71
70
|
import InfoText from '../../infoText'
|
72
71
|
import Icon from '../../icon'
|
73
72
|
import ErrorMessage from '../../errorMessage'
|
@@ -329,12 +328,8 @@ export default {
|
|
329
328
|
}
|
330
329
|
},
|
331
330
|
methods: {
|
332
|
-
|
333
|
-
this.$emit('
|
334
|
-
this.$refs.inputElement.$el.blur()
|
335
|
-
},
|
336
|
-
onChangeHandler($event) {
|
337
|
-
this.$emit('input-change', $event)
|
331
|
+
onChangeHandler(event) {
|
332
|
+
this.$emit('input-change', event.target.value)
|
338
333
|
},
|
339
334
|
onInputBlur($event) {
|
340
335
|
this.$emit('input-blur', $event.target.value)
|
@@ -13,10 +13,7 @@
|
|
13
13
|
:hasFocus="hasFocus"
|
14
14
|
:data-id="dataId"
|
15
15
|
/>
|
16
|
-
<
|
17
|
-
class="search-icn"
|
18
|
-
:src="require('../../../assets/icons/search_icon_black.svg')"
|
19
|
-
/>
|
16
|
+
<SearchIconSvg class="search-icn" />
|
20
17
|
</input-wrapper>
|
21
18
|
</container>
|
22
19
|
</template>
|
@@ -33,7 +30,8 @@
|
|
33
30
|
// :isFilter="true" // to set the height at 30px
|
34
31
|
// data-id="test-data-id"
|
35
32
|
// />
|
36
|
-
import styled from '
|
33
|
+
import styled from 'vue3-styled-components'
|
34
|
+
import SearchIconSvg from '../../../assets/icons/search_icon_black.svg'
|
37
35
|
|
38
36
|
const inputAttrs = {
|
39
37
|
isDisabled: Boolean,
|
@@ -68,7 +66,7 @@ const InputContainer = styled('input', inputAttrs)`
|
|
68
66
|
const InputWrapper = styled.span`
|
69
67
|
position: relative;
|
70
68
|
|
71
|
-
|
69
|
+
svg {
|
72
70
|
position: absolute;
|
73
71
|
right: 10px;
|
74
72
|
top: 50%;
|
@@ -81,7 +79,8 @@ export default {
|
|
81
79
|
components: {
|
82
80
|
InputContainer,
|
83
81
|
InputWrapper,
|
84
|
-
Container
|
82
|
+
Container,
|
83
|
+
SearchIconSvg
|
85
84
|
},
|
86
85
|
props: {
|
87
86
|
value: {
|
@@ -114,7 +113,7 @@ export default {
|
|
114
113
|
},
|
115
114
|
methods: {
|
116
115
|
onChangeHandler(event) {
|
117
|
-
this.$emit('on-change', event)
|
116
|
+
this.$emit('on-change', event.target.value)
|
118
117
|
},
|
119
118
|
focusInputElement() {
|
120
119
|
this.$nextTick(() => {
|
@@ -30,7 +30,9 @@
|
|
30
30
|
<select-button-wrapper :disabled="disabled">
|
31
31
|
<selectButton
|
32
32
|
ref="select"
|
33
|
+
class="select-button"
|
33
34
|
@click="toggleDropdown"
|
35
|
+
:selectWidth="selectWidth"
|
34
36
|
:selectHeight="selectHeight"
|
35
37
|
:height="height"
|
36
38
|
:selectMinHeight="selectMinHeight"
|
@@ -41,14 +43,17 @@
|
|
41
43
|
buttonFontColor || colorMode == 'dark' ? 'white' : 'black'
|
42
44
|
"
|
43
45
|
:hasError="hasError"
|
44
|
-
:
|
46
|
+
:hasNoPadding="isSearchBarVisible || !hasSelectButtonPadding"
|
45
47
|
:disabled="disabled"
|
46
|
-
@keydown
|
48
|
+
@keydown="onKeyDown"
|
47
49
|
:showBorder="showBorder"
|
48
50
|
:data-id="dataId"
|
49
51
|
:isDraggable="isDraggable"
|
50
|
-
>
|
51
|
-
<draggableInputHandle
|
52
|
+
>
|
53
|
+
<draggableInputHandle
|
54
|
+
v-if="isDraggable && !isSearchBarVisible"
|
55
|
+
:height="selectHeight"
|
56
|
+
/>
|
52
57
|
<inputText
|
53
58
|
v-if="isSearchBarVisible"
|
54
59
|
ref="searchInput"
|
@@ -63,9 +68,9 @@
|
|
63
68
|
:value="textSearch"
|
64
69
|
@keydown.stop="onKeyDown"
|
65
70
|
@input-change="searchChange"
|
66
|
-
@click.
|
71
|
+
@click.stop
|
67
72
|
/>
|
68
|
-
<selector v-else>
|
73
|
+
<selector :selectWidth="selectWidth" v-else>
|
69
74
|
<slot name="selector" :selectedValue="selectedValue"></slot>
|
70
75
|
</selector>
|
71
76
|
<Caret @click.stop="toggleCaretDropdown">
|
@@ -91,26 +96,33 @@
|
|
91
96
|
/>
|
92
97
|
</Caret>
|
93
98
|
</selectButton>
|
94
|
-
<DropdownWrapper>
|
95
|
-
<
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
99
|
+
<DropdownWrapper ref="dropdownWrapperRef">
|
100
|
+
<Teleport to="#portal-target">
|
101
|
+
<selectDropdown
|
102
|
+
ref="dropdown"
|
103
|
+
v-show="isSelectDropdownShown"
|
104
|
+
:dropdownPosition="dropdownPosition"
|
105
|
+
:hoveredIndex="hoveredIndex"
|
106
|
+
:hoveredValue="hoveredValue"
|
107
|
+
:isActive="isActive"
|
108
|
+
:optionWidth="getOptionWidth"
|
109
|
+
:hoveredBgColor="
|
110
|
+
colorMode == 'dark' ? '#000000' : dropdownBgColor
|
111
|
+
"
|
112
|
+
:bgColor="
|
113
|
+
dropdownBgColor || colorMode == 'dark' ? 'black' : 'white'
|
114
|
+
"
|
115
|
+
:fontColor="
|
116
|
+
dropdownFontColor || colorMode == 'dark' ? 'white' : 'black'
|
117
|
+
"
|
118
|
+
:fontSize="fontSize"
|
119
|
+
:selectedValue="selectedValue"
|
120
|
+
@option-selected="optionSelected"
|
121
|
+
@option-hovered="optionHovered"
|
122
|
+
>
|
123
|
+
<slot name="dropdown"></slot>
|
124
|
+
</selectDropdown>
|
125
|
+
</Teleport>
|
114
126
|
</DropdownWrapper>
|
115
127
|
</select-button-wrapper>
|
116
128
|
</input-wrapper>
|
@@ -125,8 +137,9 @@
|
|
125
137
|
// optionWidth="50%"
|
126
138
|
// label="that is a label"
|
127
139
|
// alignItems="vertical"
|
128
|
-
// label-data-id="test-
|
140
|
+
// label-data-id="test-label-data-id"
|
129
141
|
// data-id="test-data-id"
|
142
|
+
// :hasSelectButtonPadding="false"
|
130
143
|
// >
|
131
144
|
// <template #selector="{selectedValue}">
|
132
145
|
// value selected: {{selectedValue}}
|
@@ -139,7 +152,8 @@
|
|
139
152
|
// </template>
|
140
153
|
// </Select>
|
141
154
|
|
142
|
-
import
|
155
|
+
import { Teleport } from 'vue'
|
156
|
+
import styled from 'vue3-styled-components'
|
143
157
|
import InfoText from '../../infoText'
|
144
158
|
import icon from '../../icon'
|
145
159
|
import inputText from '../inputText'
|
@@ -152,13 +166,18 @@ const Caret = styled.div`
|
|
152
166
|
width: 30px;
|
153
167
|
min-width: 30px;
|
154
168
|
height: 100%;
|
155
|
-
align-items: stretch
|
156
169
|
cursor: pointer;
|
157
170
|
margin-left: auto;
|
158
171
|
`
|
159
172
|
|
160
|
-
const Selector = styled
|
161
|
-
width:
|
173
|
+
const Selector = styled('div', { selectWidth: String })`
|
174
|
+
max-width: ${(props) =>
|
175
|
+
props.selectWidth
|
176
|
+
? props.selectWidth
|
177
|
+
: '100%'}; // set to same width as the select
|
178
|
+
white-space: nowrap;
|
179
|
+
text-overflow: ellipsis;
|
180
|
+
overflow: hidden;
|
162
181
|
`
|
163
182
|
|
164
183
|
const labelAttrs = { fontSize: String, fontColor: String }
|
@@ -167,13 +186,16 @@ const InputLabel = styled('div', labelAttrs)`
|
|
167
186
|
props.theme.colors[props.fontColor]
|
168
187
|
? props.theme.colors[props.fontColor]
|
169
188
|
: props.fontColor};
|
170
|
-
font-size: ${(props) =>
|
189
|
+
font-size: ${(props) => props.fontSize};
|
171
190
|
font-weight: 700;
|
172
191
|
`
|
173
192
|
const optionalLabel = styled.span`
|
174
193
|
font-weight: 300;
|
175
194
|
`
|
176
|
-
const inputProps = {
|
195
|
+
const inputProps = {
|
196
|
+
selectWidth: String,
|
197
|
+
optionWidth: String
|
198
|
+
}
|
177
199
|
const Container = styled('div', inputProps)`
|
178
200
|
width: ${(props) => (props.selectWidth ? props.selectWidth : '100%')};
|
179
201
|
position: relative;
|
@@ -200,19 +222,22 @@ const selectButtonAttrs = {
|
|
200
222
|
hasError: Boolean,
|
201
223
|
disabled: Boolean,
|
202
224
|
selectHeight: String,
|
225
|
+
selectWidth: String,
|
203
226
|
height: String,
|
204
227
|
selectMinHeight: String,
|
205
|
-
|
228
|
+
hasNoPadding: Boolean,
|
206
229
|
showBorder: Boolean,
|
207
|
-
isDraggable: Boolean
|
230
|
+
isDraggable: Boolean
|
208
231
|
}
|
209
232
|
const selectButton = styled('div', selectButtonAttrs)`
|
210
233
|
position: relative;
|
211
234
|
box-sizing: border-box;
|
212
235
|
border-radius: 4px;
|
213
|
-
padding-left
|
236
|
+
padding-left: ${(props) =>
|
237
|
+
props.hasNoPadding ? '0' : props.isDraggable ? '30px' : '15px'};
|
214
238
|
text-align: left;
|
215
239
|
border-radius: 4px;
|
240
|
+
max-width: ${(props) => (props.selectWidth ? props.selectWidth : '100%')};
|
216
241
|
min-height: ${(props) =>
|
217
242
|
props.selectHeight
|
218
243
|
? props.selectHeight
|
@@ -223,7 +248,7 @@ const selectButton = styled('div', selectButtonAttrs)`
|
|
223
248
|
: '36px'};
|
224
249
|
display: flex;
|
225
250
|
align-items: center;
|
226
|
-
|
251
|
+
height: ${(props) => props.selectHeight};
|
227
252
|
${({ showBorder, theme, hasError }) =>
|
228
253
|
showBorder &&
|
229
254
|
`
|
@@ -241,8 +266,10 @@ const selectButton = styled('div', selectButtonAttrs)`
|
|
241
266
|
: props.fontColor};
|
242
267
|
${(props) => (props.disabled ? 'pointer-events: none' : '')};
|
243
268
|
overflow: hidden;
|
244
|
-
&
|
245
|
-
border-right
|
269
|
+
& > .handle {
|
270
|
+
border-right: ${(props) =>
|
271
|
+
props.hasError ? props.theme.colors.red : props.theme.colors.grey4}
|
272
|
+
1px solid;
|
246
273
|
}
|
247
274
|
`
|
248
275
|
const selectDropdownAttrs = {
|
@@ -252,14 +279,17 @@ const selectDropdownAttrs = {
|
|
252
279
|
selectWidth: String,
|
253
280
|
optionWidth: String,
|
254
281
|
hoveredIndex: Number,
|
282
|
+
fontSize: String,
|
283
|
+
dropdownPosition: Object,
|
255
284
|
hoveredValue: Number | String,
|
256
285
|
selectedValue: Number | String
|
257
286
|
}
|
258
287
|
const selectDropdown = styled('div', selectDropdownAttrs)`
|
259
288
|
box-sizing: border-box;
|
260
|
-
z-index:${(props) => (props.isActive ? '2' : '
|
261
|
-
position:absolute;
|
262
|
-
top:
|
289
|
+
z-index:${(props) => (props.isActive ? '2' : '99999')};
|
290
|
+
position: absolute;
|
291
|
+
top: ${(props) => props.dropdownPosition?.top}px;
|
292
|
+
left: ${(props) => props.dropdownPosition?.left}px;
|
263
293
|
border:1px solid ${(props) => props.theme.colors.grey4}
|
264
294
|
border-radius:4px;
|
265
295
|
display: flex;
|
@@ -267,7 +297,7 @@ const selectDropdown = styled('div', selectDropdownAttrs)`
|
|
267
297
|
align-items: flex-start;
|
268
298
|
padding: 0px;
|
269
299
|
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
270
|
-
width: ${(props) =>
|
300
|
+
width: ${(props) => props.optionWidth};
|
271
301
|
background-color:${(props) =>
|
272
302
|
props.theme.colors[props.bgColor]
|
273
303
|
? props.theme.colors[props.bgColor]
|
@@ -284,7 +314,9 @@ const selectDropdown = styled('div', selectDropdownAttrs)`
|
|
284
314
|
? props.theme.colors[props.hoveredBgColor]
|
285
315
|
: props.hoveredBgColor};
|
286
316
|
}
|
317
|
+
font-size: ${(props) => props.fontSize}
|
287
318
|
`
|
319
|
+
selectDropdown.emits = ['option-hovered', 'option-selected']
|
288
320
|
const DropdownWrapper = styled('div')`
|
289
321
|
position: relative;
|
290
322
|
`
|
@@ -297,6 +329,10 @@ const InputWrapper = styled('div', inputAttrs)`
|
|
297
329
|
grid-template-columns: ${(props) =>
|
298
330
|
props.alignItems === 'vertical' || !props.hasLabel ? '1fr' : 'auto 1fr'};
|
299
331
|
`
|
332
|
+
|
333
|
+
const DROPDOWN_HEIGHT_OFFSET = 4
|
334
|
+
const DROPDOWN_TOP_OFFSET = 21
|
335
|
+
|
300
336
|
export default {
|
301
337
|
name: 'RCselect',
|
302
338
|
|
@@ -307,7 +343,7 @@ export default {
|
|
307
343
|
},
|
308
344
|
fontSize: {
|
309
345
|
required: false,
|
310
|
-
default:
|
346
|
+
default: '13px'
|
311
347
|
},
|
312
348
|
label: {
|
313
349
|
required: false
|
@@ -410,6 +446,10 @@ export default {
|
|
410
446
|
type: String,
|
411
447
|
default: ''
|
412
448
|
},
|
449
|
+
hasSelectButtonPadding: {
|
450
|
+
type: Boolean,
|
451
|
+
default: true
|
452
|
+
},
|
413
453
|
isDraggable: {
|
414
454
|
type: Boolean,
|
415
455
|
default: false
|
@@ -431,6 +471,7 @@ export default {
|
|
431
471
|
Caret,
|
432
472
|
Selector,
|
433
473
|
inputText,
|
474
|
+
Teleport,
|
434
475
|
draggableInputHandle
|
435
476
|
},
|
436
477
|
|
@@ -441,23 +482,38 @@ export default {
|
|
441
482
|
isActive: false,
|
442
483
|
textSearch: '',
|
443
484
|
hoveredIndex: 0,
|
444
|
-
|
445
|
-
|
485
|
+
isClickOutsideActive: false,
|
486
|
+
dropdownPosition: {
|
487
|
+
left: null,
|
488
|
+
top: null
|
489
|
+
},
|
490
|
+
dropdownWidth: null,
|
491
|
+
hoveredValue: null
|
446
492
|
}
|
447
493
|
},
|
448
494
|
mounted() {
|
495
|
+
this.observeDropdownHeight()
|
496
|
+
this.observeSelectWidth()
|
497
|
+
window.addEventListener('resize', this.handleSetDropdownOffet)
|
498
|
+
},
|
499
|
+
beforeMount() {
|
449
500
|
this.selectedValue = this.value
|
450
501
|
document.addEventListener('click', this.clickOutside)
|
502
|
+
this.getDropdownPosition()
|
503
|
+
window.removeEventListener('resize', this.handleSetDropdownOffet)
|
504
|
+
if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
|
505
|
+
if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
|
451
506
|
},
|
452
|
-
|
507
|
+
unmounted() {
|
453
508
|
document.removeEventListener('click', this.clickOutside)
|
454
509
|
},
|
455
510
|
methods: {
|
456
511
|
focus() {
|
457
512
|
this.isActive = true
|
458
513
|
},
|
459
|
-
blur() {
|
514
|
+
blur(e) {
|
460
515
|
this.isActive = false
|
516
|
+
this.$emit('blur', e)
|
461
517
|
},
|
462
518
|
toggleDropdown() {
|
463
519
|
this.isDropdownOpen = !this.isDropdownOpen
|
@@ -473,6 +529,9 @@ export default {
|
|
473
529
|
this.blur()
|
474
530
|
this.isDropdownOpen = false
|
475
531
|
},
|
532
|
+
clearSearch() {
|
533
|
+
this.textSearch = ''
|
534
|
+
},
|
476
535
|
optionSelected(e) {
|
477
536
|
this.selectedValue = e
|
478
537
|
this.closeDropdown()
|
@@ -501,15 +560,15 @@ export default {
|
|
501
560
|
searchChange(value) {
|
502
561
|
this.textSearch = value
|
503
562
|
this.$emit('search-change', value)
|
504
|
-
this.$refs.dropdown.$children
|
505
|
-
|
506
|
-
.
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
563
|
+
const dropdownChildren = [...this.$refs.dropdown.$el.children]
|
564
|
+
dropdownChildren.forEach((el) => {
|
565
|
+
if (!el.textContent.toLowerCase().includes(value.toLowerCase())) {
|
566
|
+
el.style.display = 'none'
|
567
|
+
|
568
|
+
return
|
569
|
+
}
|
570
|
+
el.style.display = 'inherit'
|
571
|
+
})
|
513
572
|
},
|
514
573
|
onSelectSlotClick() {
|
515
574
|
this.toggleDropdown()
|
@@ -522,6 +581,7 @@ export default {
|
|
522
581
|
if (
|
523
582
|
this.$refs.select.$el == event.target ||
|
524
583
|
this.$refs.select.$el.contains(event.target) ||
|
584
|
+
event.target.id === 'more-button' ||
|
525
585
|
event.target.parentNode === dropdownRef.$el
|
526
586
|
) {
|
527
587
|
return
|
@@ -535,13 +595,92 @@ export default {
|
|
535
595
|
} else if (e.key == 'ArrowUp') {
|
536
596
|
this.onArrowPress(-1)
|
537
597
|
} else if (e.key == 'Enter') {
|
538
|
-
const optionHoveredComponent =
|
539
|
-
this
|
540
|
-
|
541
|
-
]
|
598
|
+
const optionHoveredComponent = [...this.$refs.dropdown.$el.children][
|
599
|
+
(this.hoveredIndex - 1 + this.optionLength) % this.optionLength
|
600
|
+
]
|
542
601
|
this.optionSelected(optionHoveredComponent.$el.dataset.value)
|
543
602
|
}
|
544
603
|
},
|
604
|
+
// If some part of the dropdown menu is outside viewport of the bottom of the screen,
|
605
|
+
// we need to offset it and display it at the top of the select dropdown instead
|
606
|
+
async getDropdownPosition() {
|
607
|
+
if (
|
608
|
+
!this.$refs.dropdownWrapperRef ||
|
609
|
+
!this.$refs.select ||
|
610
|
+
!this.$refs.dropdown
|
611
|
+
) {
|
612
|
+
return
|
613
|
+
}
|
614
|
+
await this.$nextTick()
|
615
|
+
const isDisplayedAtBottom = await this.generateDropdownPosition()
|
616
|
+
await this.$nextTick()
|
617
|
+
// If the dropdown menu is going to be displayed at the bottom,
|
618
|
+
// we need reverify its position after a dom update (nextTick)
|
619
|
+
if (isDisplayedAtBottom) this.generateDropdownPosition()
|
620
|
+
},
|
621
|
+
async generateDropdownPosition() {
|
622
|
+
const isDropdownNotCompletelyVisible =
|
623
|
+
await this.isBottomOfDropdownOutOfViewport()
|
624
|
+
const dropdownWrapperEl = this.$refs.dropdownWrapperRef.$el
|
625
|
+
const selectButtonHeight = this.$refs.select.$el.clientHeight
|
626
|
+
const dropdownHeight = this.$refs.dropdown.$el.clientHeight
|
627
|
+
const dropdownWrapperRelativeHeight =
|
628
|
+
dropdownWrapperEl.getBoundingClientRect().top +
|
629
|
+
window.scrollY +
|
630
|
+
DROPDOWN_HEIGHT_OFFSET
|
631
|
+
|
632
|
+
const top = isDropdownNotCompletelyVisible
|
633
|
+
? dropdownWrapperRelativeHeight
|
634
|
+
: dropdownWrapperRelativeHeight -
|
635
|
+
dropdownHeight -
|
636
|
+
selectButtonHeight -
|
637
|
+
DROPDOWN_TOP_OFFSET
|
638
|
+
const left = this.dropdownPosition.left
|
639
|
+
? this.dropdownPosition.left
|
640
|
+
: dropdownWrapperEl.getBoundingClientRect().left + window.scrollX
|
641
|
+
|
642
|
+
this.dropdownPosition = { left: Math.floor(left), top: Math.floor(top) }
|
643
|
+
|
644
|
+
return isDropdownNotCompletelyVisible
|
645
|
+
},
|
646
|
+
async isBottomOfDropdownOutOfViewport() {
|
647
|
+
if (!this.$refs.dropdown) {
|
648
|
+
return false
|
649
|
+
}
|
650
|
+
await this.$nextTick()
|
651
|
+
const rect = this.$refs.dropdown.$el.getBoundingClientRect()
|
652
|
+
const windowHeight =
|
653
|
+
window.innerHeight || document.documentElement.clientHeight
|
654
|
+
|
655
|
+
// using Math.floor because the offsets may contain decimals we are not going to consider here
|
656
|
+
return Math.floor(rect.top) + Math.floor(rect.height) <= windowHeight
|
657
|
+
},
|
658
|
+
observeDropdownHeight() {
|
659
|
+
if (!this.$refs.dropdown) return
|
660
|
+
this.dropdownResizeObserver = new ResizeObserver(() => {
|
661
|
+
this.$nextTick(() => this.getDropdownPosition())
|
662
|
+
})
|
663
|
+
this.dropdownResizeObserver.observe(this.$refs.dropdown.$el)
|
664
|
+
},
|
665
|
+
handleSetDropdownOffet() {
|
666
|
+
if (!this.$refs.select) return
|
667
|
+
this.dropdownPosition.left = Math.floor(
|
668
|
+
this.$refs.select.$el.getBoundingClientRect().left
|
669
|
+
)
|
670
|
+
this.getDropdownWidth()
|
671
|
+
},
|
672
|
+
observeSelectWidth() {
|
673
|
+
if (!this.$refs.select) return
|
674
|
+
this.selectResizeObserver = new ResizeObserver(() =>
|
675
|
+
this.$nextTick(() => this.getDropdownWidth())
|
676
|
+
)
|
677
|
+
this.selectResizeObserver.observe(this.$refs.dropdown.$el)
|
678
|
+
},
|
679
|
+
async getDropdownWidth() {
|
680
|
+
if (!this.$refs.select) return
|
681
|
+
await this.$nextTick()
|
682
|
+
this.dropdownWidth = `${this.$refs.select.$el.clientWidth}px`
|
683
|
+
},
|
545
684
|
onArrowPress(dir) {
|
546
685
|
let newHoveredElem
|
547
686
|
const currentHoveredElem = this.$refs.dropdown.$el.querySelector(
|
@@ -564,34 +703,36 @@ export default {
|
|
564
703
|
computed: {
|
565
704
|
optionLength() {
|
566
705
|
if (this.isDropdownOpen) {
|
567
|
-
|
568
|
-
const filterRef =
|
569
|
-
this.$refs.dropdown.$children &&
|
570
|
-
this.$refs.dropdown.$children.length > 1
|
571
|
-
? this.$refs.dropdown.$children
|
572
|
-
: this.$refs.dropdown.$children[0].$children
|
573
|
-
? this.$refs.dropdown.$children[0].$children
|
574
|
-
: this.$refs.dropdown.$children
|
575
|
-
return filterRef.length
|
706
|
+
return this.$refs.dropdown.$el.childElementCount
|
576
707
|
} else {
|
577
708
|
return 0
|
578
709
|
}
|
579
710
|
},
|
580
711
|
isSearchBarVisible() {
|
581
712
|
return this.isSearchable && this.optionLength >= 5 && this.isDropdownOpen
|
713
|
+
},
|
714
|
+
getOptionWidth() {
|
715
|
+
if (this.optionWidth) return this.optionWidth
|
716
|
+
|
717
|
+
return this.dropdownWidth
|
718
|
+
},
|
719
|
+
isSelectDropdownShown() {
|
720
|
+
return this.isDropdownOpen && this.dropdownPosition.left !== null
|
582
721
|
}
|
583
722
|
},
|
584
723
|
watch: {
|
585
724
|
value(val) {
|
586
725
|
this.selectedValue = val
|
587
726
|
},
|
588
|
-
isDropdownOpen(val) {
|
589
|
-
this.$emit('is-dropdown-open', val)
|
727
|
+
async isDropdownOpen(val) {
|
590
728
|
if (val) {
|
591
729
|
setTimeout(() => {
|
592
730
|
this.isClickOutsideActive = true
|
593
731
|
}, 10)
|
732
|
+
await this.$nextTick()
|
733
|
+
this.handleSetDropdownOffet()
|
594
734
|
} else {
|
735
|
+
this.dropdownPosition.left = null
|
595
736
|
setTimeout(() => {
|
596
737
|
this.isClickOutsideActive = false
|
597
738
|
}, 10)
|
@@ -22,7 +22,7 @@
|
|
22
22
|
<script>
|
23
23
|
// import selectButton from './selectButton'
|
24
24
|
// import selectDropdown from './selectDropDown'
|
25
|
-
import styled from '
|
25
|
+
import styled from 'vue3-styled-components'
|
26
26
|
const optionProps = {
|
27
27
|
isDisabled: Boolean,
|
28
28
|
hoveredBgColor: String,
|
@@ -59,7 +59,7 @@ const optionContainer = styled('div', optionProps)`
|
|
59
59
|
|
60
60
|
export default {
|
61
61
|
name: 'RCoption',
|
62
|
-
|
62
|
+
emits: ['option-hovered', 'option-selected'],
|
63
63
|
props: {
|
64
64
|
value: {
|
65
65
|
required: true
|
@@ -73,7 +73,7 @@ export default {
|
|
73
73
|
},
|
74
74
|
cursorType: {
|
75
75
|
required: false,
|
76
|
-
default: '
|
76
|
+
default: 'pointer'
|
77
77
|
},
|
78
78
|
backgroundColor: {
|
79
79
|
required: false,
|
@@ -94,12 +94,12 @@ export default {
|
|
94
94
|
return {}
|
95
95
|
},
|
96
96
|
methods: {
|
97
|
-
clickHandler() {
|
97
|
+
clickHandler(e) {
|
98
98
|
if (this.isDisabled) {
|
99
99
|
// prevent emitter if the option is disabled
|
100
100
|
return
|
101
101
|
} else {
|
102
|
-
this.$parent.$emit('option-selected', this.value)
|
102
|
+
this.$parent.$emit('option-selected', this.value, e)
|
103
103
|
}
|
104
104
|
},
|
105
105
|
hoverHandler() {
|