@eturnity/eturnity_reusable_components 7.18.0 → 7.20.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 +19 -23
- package/src/App.vue +2 -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/card/index.vue +25 -24
- package/src/components/deleteIcon/DeleteIcon.stories.js +7 -7
- package/src/components/deleteIcon/index.vue +47 -30
- package/src/components/draggableInputHandle/index.vue +24 -25
- package/src/components/dropdown/index.vue +129 -110
- package/src/components/errorMessage/index.vue +10 -5
- package/src/components/filter/filterSettings.vue +59 -97
- package/src/components/filter/index.vue +3 -3
- package/src/components/filter/parentDropdown.vue +2 -2
- package/src/components/icon/iconCache.js +23 -0
- package/src/components/icon/iconCollection.vue +2 -2
- package/src/components/icon/index.vue +67 -75
- package/src/components/iconWrapper/index.vue +1 -4
- package/src/components/infoCard/index.vue +2 -3
- package/src/components/infoText/index.vue +1 -1
- package/src/components/inputs/checkbox/index.vue +21 -6
- package/src/components/inputs/inputNumber/index.vue +8 -11
- package/src/components/inputs/inputNumberQuestion/index.vue +1 -1
- package/src/components/inputs/inputText/index.vue +3 -3
- package/src/components/inputs/radioButton/index.vue +1 -1
- package/src/components/inputs/searchInput/index.vue +28 -11
- package/src/components/inputs/select/index.vue +244 -57
- package/src/components/inputs/select/option/index.vue +43 -12
- 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 -31
- package/src/components/modals/modal/index.vue +2 -6
- package/src/components/navigationTabs/index.vue +27 -20
- package/src/components/pageSubtitle/index.vue +1 -1
- package/src/components/pageTitle/index.vue +4 -4
- package/src/components/pagination/index.vue +3 -3
- package/src/components/progressBar/index.vue +1 -1
- package/src/components/projectMarker/index.vue +16 -9
- package/src/components/sideMenu/index.vue +1 -1
- package/src/components/spinner/index.vue +7 -11
- package/src/components/tableDropdown/index.vue +35 -45
- package/src/components/tables/mainTable/exampleNested.vue +1 -1
- package/src/components/tables/mainTable/index.vue +10 -9
- 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
@@ -28,7 +28,9 @@
|
|
28
28
|
<select-button-wrapper :disabled="disabled">
|
29
29
|
<selectButton
|
30
30
|
ref="select"
|
31
|
+
class="select-button"
|
31
32
|
@click="toggleDropdown"
|
33
|
+
:selectWidth="selectWidth"
|
32
34
|
:selectHeight="selectHeight"
|
33
35
|
:height="height"
|
34
36
|
:selectMinHeight="selectMinHeight"
|
@@ -39,9 +41,9 @@
|
|
39
41
|
buttonFontColor || colorMode == 'dark' ? 'white' : 'black'
|
40
42
|
"
|
41
43
|
:hasError="hasError"
|
42
|
-
:
|
44
|
+
:hasNoPadding="isSearchBarVisible || !hasSelectButtonPadding"
|
43
45
|
:disabled="disabled"
|
44
|
-
@keydown
|
46
|
+
@keydown="onKeyDown"
|
45
47
|
:showBorder="showBorder"
|
46
48
|
:data-id="dataId"
|
47
49
|
:paddingLeft="paddingLeft"
|
@@ -64,7 +66,7 @@
|
|
64
66
|
:value="textSearch"
|
65
67
|
@keydown.stop="onKeyDown"
|
66
68
|
@input-change="searchChange"
|
67
|
-
@click.
|
69
|
+
@click.stop
|
68
70
|
/>
|
69
71
|
<selector
|
70
72
|
v-else
|
@@ -97,26 +99,33 @@
|
|
97
99
|
/>
|
98
100
|
</Caret>
|
99
101
|
</selectButton>
|
100
|
-
<DropdownWrapper>
|
101
|
-
<
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
102
|
+
<DropdownWrapper ref="dropdownWrapperRef">
|
103
|
+
<Teleport to="#portal-target">
|
104
|
+
<selectDropdown
|
105
|
+
ref="dropdown"
|
106
|
+
v-show="isSelectDropdownShown"
|
107
|
+
:dropdownPosition="dropdownPosition"
|
108
|
+
:hoveredIndex="hoveredIndex"
|
109
|
+
:hoveredValue="hoveredValue"
|
110
|
+
:isActive="isActive"
|
111
|
+
:optionWidth="getOptionWidth"
|
112
|
+
:hoveredBgColor="
|
113
|
+
colorMode == 'dark' ? '#000000' : dropdownBgColor
|
114
|
+
"
|
115
|
+
:bgColor="
|
116
|
+
dropdownBgColor || colorMode == 'dark' ? 'black' : 'white'
|
117
|
+
"
|
118
|
+
:fontColor="
|
119
|
+
dropdownFontColor || colorMode == 'dark' ? 'white' : 'black'
|
120
|
+
"
|
121
|
+
:fontSize="fontSize"
|
122
|
+
:selectedValue="selectedValue"
|
123
|
+
@option-selected="optionSelected"
|
124
|
+
@option-hovered="optionHovered"
|
125
|
+
>
|
126
|
+
<slot name="dropdown"></slot>
|
127
|
+
</selectDropdown>
|
128
|
+
</Teleport>
|
120
129
|
</DropdownWrapper>
|
121
130
|
</select-button-wrapper>
|
122
131
|
</input-wrapper>
|
@@ -131,8 +140,9 @@
|
|
131
140
|
// optionWidth="50%"
|
132
141
|
// label="that is a label"
|
133
142
|
// alignItems="vertical"
|
134
|
-
// label-data-id="test-
|
143
|
+
// label-data-id="test-label-data-id"
|
135
144
|
// data-id="test-data-id"
|
145
|
+
// :hasSelectButtonPadding="false"
|
136
146
|
// >
|
137
147
|
// <template #selector="{selectedValue}">
|
138
148
|
// value selected: {{selectedValue}}
|
@@ -145,7 +155,8 @@
|
|
145
155
|
// </template>
|
146
156
|
// </Select>
|
147
157
|
|
148
|
-
import
|
158
|
+
import { Teleport } from 'vue'
|
159
|
+
import styled from 'vue3-styled-components'
|
149
160
|
import InfoText from '../../infoText'
|
150
161
|
import icon from '../../icon'
|
151
162
|
import inputText from '../inputText'
|
@@ -161,7 +172,7 @@ const Caret = styled.div`
|
|
161
172
|
width: ${CARET_WIDTH};
|
162
173
|
min-width: ${CARET_WIDTH};
|
163
174
|
height: 100%;
|
164
|
-
align-items:
|
175
|
+
align-items: center;
|
165
176
|
cursor: pointer;
|
166
177
|
margin-left: auto;
|
167
178
|
`
|
@@ -172,7 +183,10 @@ const selectorProps = {
|
|
172
183
|
showBorder: Boolean
|
173
184
|
}
|
174
185
|
const Selector = styled('div', selectorProps)`
|
175
|
-
${(props) =>
|
186
|
+
${(props) =>
|
187
|
+
props.selectWidth === '100%'
|
188
|
+
? 'width: 100%;'
|
189
|
+
: `width: calc(${props.selectWidth} -
|
176
190
|
(
|
177
191
|
${CARET_WIDTH} +
|
178
192
|
${props.paddingLeft}
|
@@ -181,8 +195,7 @@ const Selector = styled('div', selectorProps)`
|
|
181
195
|
);
|
182
196
|
white-space: nowrap;
|
183
197
|
text-overflow: ellipsis;
|
184
|
-
overflow: hidden;`
|
185
|
-
}
|
198
|
+
overflow: hidden;`}
|
186
199
|
`
|
187
200
|
|
188
201
|
const labelAttrs = { fontSize: String, fontColor: String }
|
@@ -197,7 +210,10 @@ const InputLabel = styled('div', labelAttrs)`
|
|
197
210
|
const optionalLabel = styled.span`
|
198
211
|
font-weight: 300;
|
199
212
|
`
|
200
|
-
const inputProps = {
|
213
|
+
const inputProps = {
|
214
|
+
selectWidth: String,
|
215
|
+
optionWidth: String
|
216
|
+
}
|
201
217
|
const Container = styled('div', inputProps)`
|
202
218
|
width: ${(props) => props.selectWidth};
|
203
219
|
position: relative;
|
@@ -224,9 +240,10 @@ const selectButtonAttrs = {
|
|
224
240
|
hasError: Boolean,
|
225
241
|
disabled: Boolean,
|
226
242
|
selectHeight: String,
|
243
|
+
selectWidth: String,
|
227
244
|
height: String,
|
228
245
|
selectMinHeight: String,
|
229
|
-
|
246
|
+
hasNoPadding: Boolean,
|
230
247
|
showBorder: Boolean,
|
231
248
|
paddingLeft: String
|
232
249
|
}
|
@@ -234,8 +251,9 @@ const selectButton = styled('div', selectButtonAttrs)`
|
|
234
251
|
position: relative;
|
235
252
|
box-sizing: border-box;
|
236
253
|
border-radius: 4px;
|
254
|
+
max-width: ${(props) => (props.selectWidth ? props.selectWidth : '100%')};
|
237
255
|
${(props) =>
|
238
|
-
props.
|
256
|
+
props.hasNoPadding ? '' : `padding-left: ${props.paddingLeft}`};
|
239
257
|
text-align: left;
|
240
258
|
min-height: ${(props) =>
|
241
259
|
props.selectHeight
|
@@ -247,7 +265,7 @@ const selectButton = styled('div', selectButtonAttrs)`
|
|
247
265
|
: '36px'};
|
248
266
|
display: flex;
|
249
267
|
align-items: center;
|
250
|
-
|
268
|
+
height: ${(props) => props.selectHeight};
|
251
269
|
${({ showBorder, theme, hasError }) =>
|
252
270
|
showBorder &&
|
253
271
|
`
|
@@ -279,14 +297,17 @@ const selectDropdownAttrs = {
|
|
279
297
|
fontColor: String,
|
280
298
|
optionWidth: String,
|
281
299
|
hoveredIndex: Number,
|
300
|
+
fontSize: String,
|
301
|
+
dropdownPosition: Object,
|
282
302
|
hoveredValue: Number | String,
|
283
303
|
selectedValue: Number | String
|
284
304
|
}
|
285
305
|
const selectDropdown = styled('div', selectDropdownAttrs)`
|
286
306
|
box-sizing: border-box;
|
287
|
-
z-index: ${(props) => (props.isActive ? '2' : '
|
307
|
+
z-index: ${(props) => (props.isActive ? '2' : '99999')};
|
288
308
|
position: absolute;
|
289
|
-
top:
|
309
|
+
top: ${(props) => props.dropdownPosition?.top}px;
|
310
|
+
left: ${(props) => props.dropdownPosition?.left}px;
|
290
311
|
border: ${BORDER_WIDTH} solid ${(props) => props.theme.colors.grey4};
|
291
312
|
border-radius: 4px;
|
292
313
|
display: flex;
|
@@ -311,7 +332,9 @@ const selectDropdown = styled('div', selectDropdownAttrs)`
|
|
311
332
|
? props.theme.colors[props.hoveredBgColor]
|
312
333
|
: props.hoveredBgColor};
|
313
334
|
}
|
335
|
+
font-size: ${(props) => props.fontSize};
|
314
336
|
`
|
337
|
+
selectDropdown.emits = ['option-hovered', 'option-selected']
|
315
338
|
const DropdownWrapper = styled('div')`
|
316
339
|
position: relative;
|
317
340
|
`
|
@@ -324,6 +347,16 @@ const InputWrapper = styled('div', inputAttrs)`
|
|
324
347
|
grid-template-columns: ${(props) =>
|
325
348
|
props.alignItems === 'vertical' || !props.hasLabel ? '1fr' : 'auto 1fr'};
|
326
349
|
`
|
350
|
+
|
351
|
+
const DROPDOWN_HEIGHT_OFFSET = 4
|
352
|
+
const DROPDOWN_TOP_OFFSET = 21
|
353
|
+
const MIN_OPTION_LENGTH = 5
|
354
|
+
|
355
|
+
const DROPDOWN_MENU_POSITIONS = {
|
356
|
+
Automatic: 'automatic',
|
357
|
+
Bottom: 'bottom'
|
358
|
+
}
|
359
|
+
|
327
360
|
export default {
|
328
361
|
name: 'RCselect',
|
329
362
|
|
@@ -435,9 +468,21 @@ export default {
|
|
435
468
|
type: String,
|
436
469
|
default: ''
|
437
470
|
},
|
471
|
+
hasSelectButtonPadding: {
|
472
|
+
type: Boolean,
|
473
|
+
default: true
|
474
|
+
},
|
438
475
|
isDraggable: {
|
439
476
|
type: Boolean,
|
440
477
|
default: false
|
478
|
+
},
|
479
|
+
minOptionLength: {
|
480
|
+
type: Number,
|
481
|
+
default: MIN_OPTION_LENGTH
|
482
|
+
},
|
483
|
+
dropdownMenuPosition: {
|
484
|
+
type: String,
|
485
|
+
default: DROPDOWN_MENU_POSITIONS.Automatic // options: ['automatic', bottom]
|
441
486
|
}
|
442
487
|
},
|
443
488
|
|
@@ -456,6 +501,7 @@ export default {
|
|
456
501
|
Caret,
|
457
502
|
Selector,
|
458
503
|
inputText,
|
504
|
+
Teleport,
|
459
505
|
draggableInputHandle
|
460
506
|
},
|
461
507
|
|
@@ -467,23 +513,38 @@ export default {
|
|
467
513
|
isActive: false,
|
468
514
|
textSearch: '',
|
469
515
|
hoveredIndex: 0,
|
470
|
-
|
471
|
-
|
516
|
+
isClickOutsideActive: false,
|
517
|
+
dropdownPosition: {
|
518
|
+
left: null,
|
519
|
+
top: null
|
520
|
+
},
|
521
|
+
dropdownWidth: null,
|
522
|
+
hoveredValue: null
|
472
523
|
}
|
473
524
|
},
|
474
525
|
mounted() {
|
526
|
+
this.observeDropdownHeight()
|
527
|
+
this.observeSelectWidth()
|
528
|
+
window.addEventListener('resize', this.handleSetDropdownOffet)
|
529
|
+
},
|
530
|
+
beforeMount() {
|
475
531
|
this.selectedValue = this.value
|
476
532
|
document.addEventListener('click', this.clickOutside)
|
533
|
+
this.getDropdownPosition()
|
534
|
+
window.removeEventListener('resize', this.handleSetDropdownOffet)
|
535
|
+
if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
|
536
|
+
if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
|
477
537
|
},
|
478
|
-
|
538
|
+
unmounted() {
|
479
539
|
document.removeEventListener('click', this.clickOutside)
|
480
540
|
},
|
481
541
|
methods: {
|
482
542
|
focus() {
|
483
543
|
this.isActive = true
|
484
544
|
},
|
485
|
-
blur() {
|
545
|
+
blur(e) {
|
486
546
|
this.isActive = false
|
547
|
+
this.$emit('blur', e)
|
487
548
|
},
|
488
549
|
toggleDropdown() {
|
489
550
|
this.isDropdownOpen = !this.isDropdownOpen
|
@@ -499,6 +560,9 @@ export default {
|
|
499
560
|
this.blur()
|
500
561
|
this.isDropdownOpen = false
|
501
562
|
},
|
563
|
+
clearSearch() {
|
564
|
+
this.textSearch = ''
|
565
|
+
},
|
502
566
|
optionSelected(e) {
|
503
567
|
this.selectedValue = e
|
504
568
|
this.closeDropdown()
|
@@ -527,15 +591,15 @@ export default {
|
|
527
591
|
searchChange(value) {
|
528
592
|
this.textSearch = value
|
529
593
|
this.$emit('search-change', value)
|
530
|
-
this.$refs.dropdown.$children
|
531
|
-
|
532
|
-
.
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
594
|
+
const dropdownChildren = [...this.$refs.dropdown.$el.children]
|
595
|
+
dropdownChildren.forEach((el) => {
|
596
|
+
if (!el.textContent.toLowerCase().includes(value.toLowerCase())) {
|
597
|
+
el.style.display = 'none'
|
598
|
+
|
599
|
+
return
|
600
|
+
}
|
601
|
+
el.style.display = 'inherit'
|
602
|
+
})
|
539
603
|
},
|
540
604
|
clickOutside(event) {
|
541
605
|
const dropdownRef = this.$refs.dropdown
|
@@ -545,6 +609,7 @@ export default {
|
|
545
609
|
if (
|
546
610
|
this.$refs.select.$el == event.target ||
|
547
611
|
this.$refs.select.$el.contains(event.target) ||
|
612
|
+
event.target.id === 'more-button' ||
|
548
613
|
event.target.parentNode === dropdownRef.$el
|
549
614
|
) {
|
550
615
|
return
|
@@ -558,13 +623,101 @@ export default {
|
|
558
623
|
} else if (e.key == 'ArrowUp') {
|
559
624
|
this.onArrowPress(-1)
|
560
625
|
} else if (e.key == 'Enter') {
|
561
|
-
const optionHoveredComponent =
|
562
|
-
this
|
563
|
-
|
564
|
-
]
|
626
|
+
const optionHoveredComponent = [...this.$refs.dropdown.$el.children][
|
627
|
+
(this.hoveredIndex - 1 + this.optionLength) % this.optionLength
|
628
|
+
]
|
565
629
|
this.optionSelected(optionHoveredComponent.$el.dataset.value)
|
566
630
|
}
|
567
631
|
},
|
632
|
+
// If some part of the dropdown menu is outside viewport of the bottom of the screen,
|
633
|
+
// we need to offset it and display it at the top of the select dropdown instead
|
634
|
+
async getDropdownPosition() {
|
635
|
+
if (
|
636
|
+
!this.$refs.dropdownWrapperRef ||
|
637
|
+
!this.$refs.select ||
|
638
|
+
!this.$refs.dropdown
|
639
|
+
) {
|
640
|
+
return
|
641
|
+
}
|
642
|
+
await this.$nextTick()
|
643
|
+
const isDisplayedAtBottom = await this.generateDropdownPosition()
|
644
|
+
// If the dropdown menu is going to be displayed at the bottom,
|
645
|
+
// we need reverify its position after a dom update (nextTick)
|
646
|
+
await this.$nextTick()
|
647
|
+
if (isDisplayedAtBottom) this.generateDropdownPosition()
|
648
|
+
},
|
649
|
+
async generateDropdownPosition() {
|
650
|
+
const isDropdownNotCompletelyVisible =
|
651
|
+
await this.isBottomOfDropdownOutOfViewport()
|
652
|
+
const dropdownWrapperEl = this.$refs.dropdownWrapperRef.$el
|
653
|
+
const selectButtonHeight = this.$refs.select.$el.clientHeight
|
654
|
+
const dropdownHeight = this.$refs.dropdown.$el.clientHeight
|
655
|
+
const dropdownWrapperRelativeHeight =
|
656
|
+
dropdownWrapperEl.getBoundingClientRect().top +
|
657
|
+
window.scrollY +
|
658
|
+
DROPDOWN_HEIGHT_OFFSET
|
659
|
+
|
660
|
+
const top =
|
661
|
+
isDropdownNotCompletelyVisible ||
|
662
|
+
(!isDropdownNotCompletelyVisible &&
|
663
|
+
this.dropdownMenuPosition === DROPDOWN_MENU_POSITIONS.Bottom)
|
664
|
+
? dropdownWrapperRelativeHeight
|
665
|
+
: dropdownWrapperRelativeHeight -
|
666
|
+
dropdownHeight -
|
667
|
+
selectButtonHeight -
|
668
|
+
DROPDOWN_TOP_OFFSET
|
669
|
+
const left = this.dropdownPosition.left
|
670
|
+
? this.dropdownPosition.left
|
671
|
+
: dropdownWrapperEl.getBoundingClientRect().left + window.scrollX
|
672
|
+
|
673
|
+
this.dropdownPosition = { left: Math.floor(left), top: Math.floor(top) }
|
674
|
+
|
675
|
+
return isDropdownNotCompletelyVisible
|
676
|
+
},
|
677
|
+
async isBottomOfDropdownOutOfViewport() {
|
678
|
+
if (
|
679
|
+
!this.$refs.dropdown ||
|
680
|
+
this.dropdownMenuPosition === DROPDOWN_MENU_POSITIONS.Bottom
|
681
|
+
) {
|
682
|
+
return false
|
683
|
+
}
|
684
|
+
|
685
|
+
await this.$nextTick()
|
686
|
+
const rect = this.$refs.dropdown.$el.getBoundingClientRect()
|
687
|
+
const windowHeight =
|
688
|
+
window.innerHeight || document.documentElement.clientHeight
|
689
|
+
|
690
|
+
if (windowHeight <= 650) return true
|
691
|
+
|
692
|
+
// using Math.floor because the offsets may contain decimals we are not going to consider here
|
693
|
+
return Math.floor(rect.top) + Math.floor(rect.height) <= windowHeight
|
694
|
+
},
|
695
|
+
observeDropdownHeight() {
|
696
|
+
if (!this.$refs.dropdown) return
|
697
|
+
this.dropdownResizeObserver = new ResizeObserver(() => {
|
698
|
+
this.$nextTick(() => this.getDropdownPosition())
|
699
|
+
})
|
700
|
+
this.dropdownResizeObserver.observe(this.$refs.dropdown.$el)
|
701
|
+
},
|
702
|
+
handleSetDropdownOffet() {
|
703
|
+
if (!this.$refs.select) return
|
704
|
+
this.dropdownPosition.left = Math.floor(
|
705
|
+
this.$refs.select.$el.getBoundingClientRect().left
|
706
|
+
)
|
707
|
+
this.getDropdownWidth()
|
708
|
+
},
|
709
|
+
observeSelectWidth() {
|
710
|
+
if (!this.$refs.select) return
|
711
|
+
this.selectResizeObserver = new ResizeObserver(() =>
|
712
|
+
this.$nextTick(() => this.getDropdownWidth())
|
713
|
+
)
|
714
|
+
this.selectResizeObserver.observe(this.$refs.dropdown.$el)
|
715
|
+
},
|
716
|
+
async getDropdownWidth() {
|
717
|
+
if (!this.$refs.select) return
|
718
|
+
await this.$nextTick()
|
719
|
+
this.dropdownWidth = `${this.$refs.select.$el.clientWidth}px`
|
720
|
+
},
|
568
721
|
onArrowPress(dir) {
|
569
722
|
let newHoveredElem
|
570
723
|
const currentHoveredElem = this.$refs.dropdown.$el.querySelector(
|
@@ -590,33 +743,67 @@ export default {
|
|
590
743
|
computed: {
|
591
744
|
optionLength() {
|
592
745
|
if (this.isDropdownOpen) {
|
593
|
-
return this.$refs.dropdown.$el.childElementCount
|
746
|
+
return this.$refs.dropdown.$el.childElementCount > 1
|
747
|
+
? this.$refs.dropdown.$el.childElementCount
|
748
|
+
: this.$refs.dropdown.$el.children[0].childElementCount
|
594
749
|
}
|
595
750
|
|
596
751
|
return 0
|
597
752
|
},
|
598
753
|
isSearchBarVisible() {
|
599
|
-
return
|
754
|
+
return (
|
755
|
+
this.isSearchable &&
|
756
|
+
this.optionLength >= this.minOptionLength &&
|
757
|
+
this.isDropdownOpen
|
758
|
+
)
|
759
|
+
},
|
760
|
+
getOptionWidth() {
|
761
|
+
if (this.optionWidth) return this.optionWidth
|
762
|
+
|
763
|
+
return this.dropdownWidth
|
764
|
+
},
|
765
|
+
isSelectDropdownShown() {
|
766
|
+
return (
|
767
|
+
this.isDropdownOpen &&
|
768
|
+
this.dropdownPosition.left !== null &&
|
769
|
+
(!this.isSearchable || this.isSearchable)
|
770
|
+
)
|
771
|
+
},
|
772
|
+
isMobileDevice() {
|
773
|
+
const userAgent = navigator.userAgent || navigator.vendor || window.opera
|
774
|
+
const touchCapable =
|
775
|
+
'ontouchstart' in window ||
|
776
|
+
navigator.maxTouchPoints > 0 ||
|
777
|
+
navigator.msMaxTouchPoints > 0
|
778
|
+
|
779
|
+
return (
|
780
|
+
/Android/i.test(userAgent) ||
|
781
|
+
/iPad|iPhone|iPod/.test(userAgent) ||
|
782
|
+
(/Macintosh/.test(userAgent) && touchCapable) ||
|
783
|
+
/windows phone/i.test(userAgent)
|
784
|
+
)
|
600
785
|
}
|
601
786
|
},
|
602
787
|
watch: {
|
603
788
|
value(val) {
|
604
789
|
this.selectedValue = val
|
605
790
|
},
|
606
|
-
isDropdownOpen(val) {
|
607
|
-
this.$emit('is-dropdown-open', val)
|
791
|
+
async isDropdownOpen(val) {
|
608
792
|
if (val) {
|
609
793
|
setTimeout(() => {
|
610
794
|
this.isClickOutsideActive = true
|
611
795
|
}, 10)
|
796
|
+
await this.$nextTick()
|
797
|
+
this.handleSetDropdownOffet()
|
612
798
|
} else {
|
799
|
+
this.dropdownPosition.left = null
|
613
800
|
setTimeout(() => {
|
614
801
|
this.isClickOutsideActive = false
|
615
802
|
}, 10)
|
616
803
|
}
|
617
804
|
if (val && this.isSearchable) {
|
618
805
|
this.$nextTick(() => {
|
619
|
-
if (this.$refs.searchInput) {
|
806
|
+
if (this.$refs.searchInput && !this.isMobileDevice) {
|
620
807
|
this.$refs.searchInput.$el.querySelector('input').focus()
|
621
808
|
}
|
622
809
|
})
|
@@ -12,8 +12,11 @@
|
|
12
12
|
@mouseover="hoverHandler"
|
13
13
|
:cursorType="cursorType"
|
14
14
|
:isDisabled="isDisabled"
|
15
|
+
:disabledBgColor="disabledBgColor"
|
16
|
+
:disabledTextColor="disabledTextColor"
|
15
17
|
:backgroundColor="colorMode == 'dark' ? '#000000' : backgroundColor"
|
16
18
|
:title="hoverText"
|
19
|
+
:padding="padding"
|
17
20
|
>
|
18
21
|
<slot></slot>
|
19
22
|
</optionContainer>
|
@@ -22,12 +25,15 @@
|
|
22
25
|
<script>
|
23
26
|
// import selectButton from './selectButton'
|
24
27
|
// import selectDropdown from './selectDropDown'
|
25
|
-
import styled from '
|
28
|
+
import styled from 'vue3-styled-components'
|
26
29
|
const optionProps = {
|
27
30
|
isDisabled: Boolean,
|
28
31
|
hoveredBgColor: String,
|
29
32
|
cursorType: String,
|
30
|
-
backgroundColor: String
|
33
|
+
backgroundColor: String,
|
34
|
+
disabledBgColor: String,
|
35
|
+
disabledTextColor: String,
|
36
|
+
padding: String
|
31
37
|
}
|
32
38
|
const optionContainer = styled('div', optionProps)`
|
33
39
|
display: flex;
|
@@ -35,23 +41,37 @@ const optionContainer = styled('div', optionProps)`
|
|
35
41
|
flex-direction: row;
|
36
42
|
justify-content: space-between;
|
37
43
|
align-items: center;
|
38
|
-
padding:
|
44
|
+
padding: ${(props) => props.padding};
|
39
45
|
gap: 14px;
|
40
46
|
width: 100%;
|
41
47
|
background-color: ${(props) =>
|
42
|
-
props.
|
48
|
+
props.isDisabled
|
49
|
+
? props.theme.colors[props.disabledBgColor]
|
50
|
+
? props.theme.colors[props.disabledBgColor]
|
51
|
+
: props.disabledBgColor
|
52
|
+
: props.theme.colors[props.backgroundColor]
|
43
53
|
? props.theme.colors[props.backgroundColor]
|
44
|
-
: props.backgroundColor};
|
54
|
+
: props.backgroundColor} !important;
|
45
55
|
box-sizing: inherit;
|
46
56
|
background-color: ${(props) =>
|
47
57
|
props.theme.colors[props.backgroundColor]
|
48
58
|
? props.theme.colors[props.backgroundColor]
|
49
59
|
: props.backgroundColor};
|
50
60
|
color: ${(props) =>
|
51
|
-
props.isDisabled
|
61
|
+
props.isDisabled
|
62
|
+
? !!props.disabledTextColor
|
63
|
+
? props.theme.colors[props.disabledTextColor]
|
64
|
+
? props.theme.colors[props.disabledTextColor]
|
65
|
+
: props.disabledTextColor
|
66
|
+
: props.theme.colors.grey3
|
67
|
+
: 'inherit'};
|
52
68
|
&:hover {
|
53
69
|
background-color: ${(props) =>
|
54
|
-
props.
|
70
|
+
!!props.disabledTextColor && props.isDisabled
|
71
|
+
? props.theme.colors[props.disabledBgColor]
|
72
|
+
? props.theme.colors[props.disabledBgColor]
|
73
|
+
: props.disabledBgColor
|
74
|
+
: props.theme.colors[props.hoveredBgColor]
|
55
75
|
? props.theme.colors[props.hoveredBgColor]
|
56
76
|
: props.hoveredBgColor} !important;
|
57
77
|
}
|
@@ -59,7 +79,7 @@ const optionContainer = styled('div', optionProps)`
|
|
59
79
|
|
60
80
|
export default {
|
61
81
|
name: 'RCoption',
|
62
|
-
|
82
|
+
emits: ['option-hovered', 'option-selected'],
|
63
83
|
props: {
|
64
84
|
value: {
|
65
85
|
required: true
|
@@ -73,7 +93,7 @@ export default {
|
|
73
93
|
},
|
74
94
|
cursorType: {
|
75
95
|
required: false,
|
76
|
-
default: '
|
96
|
+
default: 'pointer'
|
77
97
|
},
|
78
98
|
backgroundColor: {
|
79
99
|
required: false,
|
@@ -85,21 +105,32 @@ export default {
|
|
85
105
|
isDisabled: {
|
86
106
|
required: false,
|
87
107
|
default: false
|
108
|
+
},
|
109
|
+
disabledBgColor: {
|
110
|
+
required: false,
|
111
|
+
default: 'white'
|
112
|
+
},
|
113
|
+
disabledTextColor: {
|
114
|
+
required: false,
|
115
|
+
default: null
|
116
|
+
},
|
117
|
+
padding: {
|
118
|
+
required: false,
|
119
|
+
default: '12px 10px'
|
88
120
|
}
|
89
121
|
},
|
90
122
|
|
91
123
|
components: { optionContainer },
|
92
|
-
|
93
124
|
data() {
|
94
125
|
return {}
|
95
126
|
},
|
96
127
|
methods: {
|
97
|
-
clickHandler() {
|
128
|
+
clickHandler(e) {
|
98
129
|
if (this.isDisabled) {
|
99
130
|
// prevent emitter if the option is disabled
|
100
131
|
return
|
101
132
|
} else {
|
102
|
-
this.$parent.$emit('option-selected', this.value)
|
133
|
+
this.$parent.$emit('option-selected', this.value, e)
|
103
134
|
}
|
104
135
|
},
|
105
136
|
hoverHandler() {
|