@eturnity/eturnity_reusable_components 7.24.3-EPDM-10576.1 → 7.24.3-EPDM-11320.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/.eslintrc.js +125 -0
- package/package.json +6 -20
- package/src/App.vue +75 -70
- package/src/components/addNewButton/index.vue +24 -27
- package/src/components/banner/actionBanner/index.vue +32 -30
- package/src/components/banner/banner/index.vue +88 -80
- package/src/components/banner/infoBanner/index.vue +36 -44
- package/src/components/buttons/buttonIcon/index.vue +83 -78
- package/src/components/buttons/closeButton/index.vue +26 -26
- package/src/components/buttons/mainButton/index.vue +80 -76
- package/src/components/card/index.vue +56 -52
- package/src/components/collapsableInfoText/index.vue +81 -76
- package/src/components/deleteIcon/index.vue +31 -28
- package/src/components/draggableInputHandle/index.vue +20 -17
- package/src/components/dropdown/Dropdown.stories.js +8 -8
- package/src/components/dropdown/index.vue +75 -72
- package/src/components/errorMessage/index.vue +23 -23
- package/src/components/filter/filterSettings.vue +349 -333
- package/src/components/filter/index.vue +130 -130
- package/src/components/filter/parentDropdown.vue +43 -40
- package/src/components/icon/Icons.stories.js +4 -4
- package/src/components/icon/iconCache.js +1 -1
- package/src/components/icon/iconCollection.vue +40 -37
- package/src/components/icon/index.vue +72 -65
- package/src/components/iconWrapper/index.vue +122 -118
- package/src/components/infoCard/index.vue +20 -17
- package/src/components/infoText/index.vue +88 -82
- package/src/components/inputs/checkbox/index.vue +91 -94
- package/src/components/inputs/inputNumber/index.vue +508 -488
- package/src/components/inputs/inputNumberQuestion/index.vue +127 -124
- package/src/components/inputs/inputText/index.vue +265 -252
- package/src/components/inputs/radioButton/index.vue +135 -120
- package/src/components/inputs/searchInput/index.vue +84 -81
- package/src/components/inputs/select/index.vue +644 -631
- package/src/components/inputs/select/option/index.vue +91 -91
- package/src/components/inputs/select/select.stories.js +7 -7
- package/src/components/inputs/slider/index.vue +46 -46
- package/src/components/inputs/switchField/index.vue +159 -152
- package/src/components/inputs/textAreaInput/index.vue +120 -113
- package/src/components/inputs/toggle/index.vue +137 -127
- package/src/components/label/index.vue +64 -61
- package/src/components/markerItem/index.vue +40 -40
- package/src/components/modals/actionModal/index.vue +32 -29
- package/src/components/modals/infoModal/index.vue +34 -27
- package/src/components/modals/modal/index.vue +88 -80
- package/src/components/navigationTabs/index.vue +50 -47
- package/src/components/pageSubtitle/index.vue +33 -29
- package/src/components/pageTitle/index.vue +47 -39
- package/src/components/pagination/index.vue +64 -62
- package/src/components/progressBar/index.vue +70 -67
- package/src/components/projectMarker/index.vue +172 -163
- package/src/components/rangeSlider/Slider.vue +449 -449
- package/src/components/rangeSlider/index.vue +282 -270
- package/src/components/rangeSlider/utils/dom.js +3 -3
- package/src/components/selectedOptions/index.vue +51 -51
- package/src/components/sideMenu/index.vue +117 -109
- package/src/components/spinner/index.vue +37 -34
- package/src/components/tableDropdown/index.vue +343 -326
- package/src/components/tables/mainTable/index.vue +109 -106
- package/src/components/tables/viewTable/index.vue +105 -92
- package/src/components/threeDots/index.vue +174 -171
- package/src/components/videoThumbnail/index.vue +67 -59
- package/src/components/videoThumbnail/videoThumbnail.stories.js +6 -6
- package/.prettierrc +0 -7
- package/public/favicon.ico +0 -0
- package/public/index.html +0 -17
@@ -1,144 +1,157 @@
|
|
1
1
|
<template>
|
2
2
|
<Container
|
3
|
-
:
|
4
|
-
:
|
3
|
+
:no-relative="noRelative"
|
4
|
+
:select-width="selectWidth"
|
5
5
|
@mouseenter="mouseEnterHandler"
|
6
6
|
@mouseleave="mouseLeaveHandler"
|
7
7
|
>
|
8
|
-
<
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
8
|
+
<InputWrapper
|
9
|
+
:align-items="alignItems"
|
10
|
+
:has-label="!!label && label.length > 0"
|
11
|
+
:no-relative="noRelative"
|
12
12
|
>
|
13
|
-
<
|
14
|
-
|
15
|
-
|
13
|
+
<LabelWrapper
|
14
|
+
v-if="label"
|
15
|
+
:data-id="labelDataId"
|
16
|
+
>
|
17
|
+
<InputLabel
|
18
|
+
:font-color="
|
16
19
|
labelFontColor || colorMode == 'dark' ? 'white' : 'eturnityGrey'
|
17
20
|
"
|
18
|
-
:
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
:font-size="fontSize"
|
22
|
+
>
|
23
|
+
{{ label }}
|
24
|
+
<OptionalLabel v-if="labelOptional">
|
25
|
+
({{ $gettext('Optional') }})
|
26
|
+
</OptionalLabel>
|
27
|
+
</InputLabel>
|
28
|
+
<InfoText
|
25
29
|
v-if="infoTextMessage"
|
26
|
-
:text="infoTextMessage"
|
27
30
|
:size="infoTextSize"
|
31
|
+
:text="infoTextMessage"
|
28
32
|
/>
|
29
|
-
</
|
30
|
-
<
|
31
|
-
<
|
33
|
+
</LabelWrapper>
|
34
|
+
<SelectButtonWrapper :disabled="disabled">
|
35
|
+
<SelectButton
|
32
36
|
ref="select"
|
33
|
-
|
34
|
-
@click="toggleDropdown"
|
35
|
-
:selectWidth="selectWidth"
|
36
|
-
:selectHeight="selectHeight"
|
37
|
-
:height="height"
|
38
|
-
:selectMinHeight="selectMinHeight"
|
39
|
-
:bgColor="
|
37
|
+
:bg-color="
|
40
38
|
buttonBgColor || colorMode == 'dark' ? 'transparentBlack1' : 'white'
|
41
39
|
"
|
42
|
-
|
40
|
+
class="select-button"
|
41
|
+
:data-id="dataId"
|
42
|
+
:disabled="disabled"
|
43
|
+
:font-color="
|
43
44
|
buttonFontColor || colorMode == 'dark' ? 'white' : 'black'
|
44
45
|
"
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
46
|
+
:font-size="fontSize"
|
47
|
+
:has-error="hasError"
|
48
|
+
:has-no-padding="isSearchBarVisible || !hasSelectButtonPadding"
|
49
|
+
:height="height"
|
50
|
+
:no-relative="noRelative"
|
51
|
+
:padding-left="paddingLeft"
|
52
|
+
:select-height="selectHeight"
|
53
|
+
:select-min-height="selectMinHeight"
|
54
|
+
:select-width="selectWidth"
|
55
|
+
:show-border="showBorder"
|
56
|
+
:show-disabled-background="showDisabledBackground"
|
57
|
+
:table-padding-left="tablePaddingLeft"
|
58
|
+
@click="toggleDropdown"
|
49
59
|
@keydown="onKeyDown"
|
50
|
-
:showBorder="showBorder"
|
51
|
-
:data-id="dataId"
|
52
|
-
:paddingLeft="paddingLeft"
|
53
|
-
:tablePaddingLeft="tablePaddingLeft"
|
54
|
-
:noRelative="noRelative"
|
55
|
-
:showDisabledBackground="showDisabledBackground"
|
56
60
|
>
|
57
|
-
<
|
61
|
+
<DraggableInputHandle
|
58
62
|
v-if="isDraggable && !isSearchBarVisible"
|
59
63
|
:height="selectHeight"
|
60
64
|
/>
|
61
|
-
<
|
65
|
+
<InputText
|
62
66
|
v-if="isSearchBarVisible"
|
63
67
|
ref="searchInput"
|
64
|
-
|
65
|
-
|
66
|
-
:noBorder="true"
|
67
|
-
:fontSize="fontSize"
|
68
|
-
backgroundColor="transparent"
|
69
|
-
:fontColor="
|
68
|
+
background-color="transparent"
|
69
|
+
:font-color="
|
70
70
|
buttonFontColor || colorMode == 'dark' ? 'white' : 'black'
|
71
71
|
"
|
72
|
+
:font-size="fontSize"
|
73
|
+
input-height="34px"
|
74
|
+
:input-width="computedWidth"
|
75
|
+
:no-border="true"
|
76
|
+
tabindex="0"
|
72
77
|
:value="textSearch"
|
73
|
-
:inputWidth="computedWidth"
|
74
|
-
@keydown.stop="onKeyDown"
|
75
|
-
@input-change="searchChange"
|
76
78
|
@click.stop
|
79
|
+
@input-change="searchChange"
|
80
|
+
@keydown.stop="onKeyDown"
|
77
81
|
/>
|
78
|
-
<
|
82
|
+
<Selector
|
79
83
|
v-else
|
80
|
-
:
|
81
|
-
:
|
82
|
-
:
|
84
|
+
:padding-left="paddingLeft"
|
85
|
+
:select-width="selectWidth"
|
86
|
+
:show-border="showBorder"
|
87
|
+
>
|
88
|
+
<slot
|
89
|
+
name="selector"
|
90
|
+
:selected-value="selectedValue"
|
91
|
+
></slot>
|
92
|
+
</Selector>
|
93
|
+
<Caret
|
94
|
+
class="caret_dropdown"
|
95
|
+
@click.stop="toggleCaretDropdown"
|
83
96
|
>
|
84
|
-
<
|
85
|
-
</selector>
|
86
|
-
<Caret @click.stop="toggleCaretDropdown" class="caret_dropdown">
|
87
|
-
<icon
|
97
|
+
<RCIcon
|
88
98
|
v-if="isDropdownOpen"
|
89
|
-
name="arrow_up"
|
90
|
-
size="12px"
|
91
99
|
:color="
|
92
100
|
caretColor || colorMode == 'dark'
|
93
101
|
? 'white'
|
94
102
|
: 'transparentBlack1'
|
95
103
|
"
|
104
|
+
name="arrow_up"
|
105
|
+
size="12px"
|
96
106
|
/>
|
97
|
-
<
|
107
|
+
<RCIcon
|
98
108
|
v-else
|
99
|
-
name="arrow_down"
|
100
|
-
size="12px"
|
101
109
|
:color="
|
102
110
|
caretColor || colorMode == 'dark'
|
103
111
|
? 'white'
|
104
112
|
: 'transparentBlack1'
|
105
113
|
"
|
114
|
+
name="arrow_down"
|
115
|
+
size="12px"
|
106
116
|
/>
|
107
117
|
</Caret>
|
108
|
-
</
|
109
|
-
<DropdownWrapper
|
118
|
+
</SelectButton>
|
119
|
+
<DropdownWrapper
|
120
|
+
ref="dropdownWrapperRef"
|
121
|
+
:no-relative="noRelative"
|
122
|
+
>
|
110
123
|
<Teleport to="#portal-target">
|
111
|
-
<
|
112
|
-
ref="dropdown"
|
124
|
+
<SelectDropdown
|
113
125
|
v-show="isSelectDropdownShown"
|
114
|
-
|
115
|
-
:
|
116
|
-
:hoveredValue="hoveredValue"
|
117
|
-
:isActive="isActive"
|
118
|
-
:optionWidth="getOptionWidth"
|
119
|
-
:hoveredBgColor="
|
120
|
-
colorMode == 'dark' ? '#000000' : dropdownBgColor
|
121
|
-
"
|
122
|
-
:bgColor="
|
126
|
+
ref="dropdown"
|
127
|
+
:bg-color="
|
123
128
|
dropdownBgColor || colorMode == 'dark' ? 'black' : 'white'
|
124
129
|
"
|
125
|
-
:
|
130
|
+
:dropdown-position="dropdownPosition"
|
131
|
+
:font-color="
|
126
132
|
dropdownFontColor || colorMode == 'dark' ? 'white' : 'black'
|
127
133
|
"
|
128
|
-
:
|
129
|
-
:
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
+
:font-size="fontSize"
|
135
|
+
:hovered-bg-color="
|
136
|
+
colorMode == 'dark' ? '#000000' : dropdownBgColor
|
137
|
+
"
|
138
|
+
:hovered-index="hoveredIndex"
|
139
|
+
:hovered-value="hoveredValue"
|
140
|
+
:is-active="isActive"
|
141
|
+
:min-width="minWidth"
|
142
|
+
:no-relative="noRelative"
|
143
|
+
:option-width="getOptionWidth"
|
144
|
+
:selected-value="selectedValue"
|
134
145
|
@mouseleave="optionLeave"
|
146
|
+
@option-hovered="optionHovered"
|
147
|
+
@option-selected="optionSelected"
|
135
148
|
>
|
136
149
|
<slot name="dropdown"></slot>
|
137
|
-
</
|
150
|
+
</SelectDropdown>
|
138
151
|
</Teleport>
|
139
152
|
</DropdownWrapper>
|
140
|
-
</
|
141
|
-
</
|
153
|
+
</SelectButtonWrapper>
|
154
|
+
</InputWrapper>
|
142
155
|
</Container>
|
143
156
|
</template>
|
144
157
|
|
@@ -166,17 +179,17 @@
|
|
166
179
|
// </template>
|
167
180
|
// </Select>
|
168
181
|
|
169
|
-
import { Teleport } from 'vue'
|
170
|
-
import styled from 'vue3-styled-components'
|
171
|
-
import InfoText from '../../infoText'
|
172
|
-
import
|
173
|
-
import
|
174
|
-
import
|
182
|
+
import { Teleport } from 'vue'
|
183
|
+
import styled from 'vue3-styled-components'
|
184
|
+
import InfoText from '../../infoText'
|
185
|
+
import RCIcon from '../../icon'
|
186
|
+
import InputText from '../inputText'
|
187
|
+
import DraggableInputHandle from '../../draggableInputHandle'
|
175
188
|
|
176
|
-
const CARET_WIDTH = '30px'
|
177
|
-
const BORDER_WIDTH = '1px'
|
189
|
+
const CARET_WIDTH = '30px'
|
190
|
+
const BORDER_WIDTH = '1px'
|
178
191
|
|
179
|
-
const Caret = styled.div`
|
192
|
+
const Caret = styled.div`
|
180
193
|
display: flex;
|
181
194
|
align-items: center;
|
182
195
|
justify-content: center;
|
@@ -188,12 +201,12 @@ const Caret = styled.div`
|
|
188
201
|
margin-left: auto;
|
189
202
|
`
|
190
203
|
|
191
|
-
const selectorProps = {
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
}
|
196
|
-
const Selector = styled('div', selectorProps)`
|
204
|
+
const selectorProps = {
|
205
|
+
selectWidth: String,
|
206
|
+
paddingLeft: String,
|
207
|
+
showBorder: Boolean
|
208
|
+
}
|
209
|
+
const Selector = styled('div', selectorProps)`
|
197
210
|
${(props) =>
|
198
211
|
props.selectWidth === '100%'
|
199
212
|
? 'width: 100%;'
|
@@ -209,29 +222,29 @@ const Selector = styled('div', selectorProps)`
|
|
209
222
|
overflow: hidden;`}
|
210
223
|
`
|
211
224
|
|
212
|
-
const labelAttrs = { fontSize: String, fontColor: String }
|
213
|
-
const InputLabel = styled('div', labelAttrs)`
|
225
|
+
const labelAttrs = { fontSize: String, fontColor: String }
|
226
|
+
const InputLabel = styled('div', labelAttrs)`
|
214
227
|
color: ${(props) =>
|
215
228
|
props.theme.colors[props.fontColor]
|
216
229
|
? props.theme.colors[props.fontColor]
|
217
|
-
|
230
|
+
: props.fontColor};
|
218
231
|
font-size: ${(props) => props.fontSize};
|
219
232
|
font-weight: 700;
|
220
233
|
`
|
221
|
-
const
|
234
|
+
const OptionalLabel = styled.span`
|
222
235
|
font-weight: 300;
|
223
236
|
`
|
224
|
-
const inputProps = {
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
}
|
229
|
-
const Container = styled('div', inputProps)`
|
237
|
+
const inputProps = {
|
238
|
+
selectWidth: String,
|
239
|
+
optionWidth: String,
|
240
|
+
noRelative: Boolean
|
241
|
+
}
|
242
|
+
const Container = styled('div', inputProps)`
|
230
243
|
width: ${(props) => props.selectWidth};
|
231
244
|
position: ${(props) => (props.noRelative ? 'static' : 'relative')};
|
232
245
|
display: inline-block;
|
233
246
|
`
|
234
|
-
const LabelWrapper = styled.div`
|
247
|
+
const LabelWrapper = styled.div`
|
235
248
|
display: inline-grid;
|
236
249
|
grid-template-columns: auto auto;
|
237
250
|
grid-gap: 12px;
|
@@ -239,30 +252,30 @@ const LabelWrapper = styled.div`
|
|
239
252
|
justify-content: start;
|
240
253
|
`
|
241
254
|
|
242
|
-
const SelectButtonWrapperAttrs = {
|
243
|
-
|
244
|
-
}
|
245
|
-
const SelectButtonWrapper = styled('div', SelectButtonWrapperAttrs)`
|
255
|
+
const SelectButtonWrapperAttrs = {
|
256
|
+
disabled: Boolean
|
257
|
+
}
|
258
|
+
const SelectButtonWrapper = styled('div', SelectButtonWrapperAttrs)`
|
246
259
|
${(props) => (props.disabled ? 'cursor: not-allowed' : 'cursor: pointer')};
|
247
260
|
`
|
248
261
|
|
249
|
-
const selectButtonAttrs = {
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
}
|
265
|
-
const
|
262
|
+
const selectButtonAttrs = {
|
263
|
+
bgColor: String,
|
264
|
+
fontColor: String,
|
265
|
+
hasError: Boolean,
|
266
|
+
disabled: Boolean,
|
267
|
+
selectHeight: String,
|
268
|
+
selectWidth: String,
|
269
|
+
height: String,
|
270
|
+
selectMinHeight: String,
|
271
|
+
hasNoPadding: Boolean,
|
272
|
+
showBorder: Boolean,
|
273
|
+
paddingLeft: String,
|
274
|
+
noRelative: Boolean,
|
275
|
+
tablePaddingLeft: String,
|
276
|
+
showDisabledBackground: Boolean
|
277
|
+
}
|
278
|
+
const SelectButton = styled('div', selectButtonAttrs)`
|
266
279
|
position: ${(props) => (props.noRelative ? 'static' : 'relative')};
|
267
280
|
box-sizing: border-box;
|
268
281
|
border-radius: 4px;
|
@@ -276,7 +289,7 @@ const selectButton = styled('div', selectButtonAttrs)`
|
|
276
289
|
: props.tablePaddingLeft
|
277
290
|
? props.tablePaddingLeft
|
278
291
|
: props.paddingLeft
|
279
|
-
|
292
|
+
}`};
|
280
293
|
text-align: left;
|
281
294
|
min-height: ${(props) =>
|
282
295
|
props.selectHeight
|
@@ -285,7 +298,7 @@ const selectButton = styled('div', selectButtonAttrs)`
|
|
285
298
|
? props.selectMinHeight
|
286
299
|
: props.height
|
287
300
|
? props.height
|
288
|
-
|
301
|
+
: '36px'};
|
289
302
|
display: flex;
|
290
303
|
align-items: center;
|
291
304
|
height: ${(props) => props.selectHeight};
|
@@ -301,38 +314,38 @@ const selectButton = styled('div', selectButtonAttrs)`
|
|
301
314
|
? props.theme.colors.grey5
|
302
315
|
: props.theme.colors[props.bgColor]
|
303
316
|
? props.theme.colors[props.bgColor]
|
304
|
-
|
317
|
+
: props.bgColor};
|
305
318
|
color: ${(props) =>
|
306
319
|
props.theme.colors[props.fontColor]
|
307
320
|
? props.theme.colors[props.fontColor]
|
308
|
-
|
321
|
+
: props.fontColor};
|
309
322
|
${(props) => (props.disabled ? 'pointer-events: none' : '')};
|
310
323
|
overflow: hidden;
|
311
324
|
& > .handle {
|
312
325
|
border-right: ${(props) =>
|
313
|
-
|
326
|
+
props.hasError ? props.theme.colors.red : props.theme.colors.grey4}
|
314
327
|
1px solid;
|
315
328
|
}
|
316
329
|
`
|
317
|
-
const selectDropdownAttrs = {
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
}
|
330
|
-
const
|
330
|
+
const selectDropdownAttrs = {
|
331
|
+
hoveredBgColor: String,
|
332
|
+
bgColor: String,
|
333
|
+
fontColor: String,
|
334
|
+
optionWidth: String,
|
335
|
+
hoveredIndex: Number,
|
336
|
+
fontSize: String,
|
337
|
+
dropdownPosition: Object,
|
338
|
+
hoveredValue: Number | String,
|
339
|
+
selectedValue: Number | String,
|
340
|
+
noRelative: Boolean,
|
341
|
+
minWidth: String
|
342
|
+
}
|
343
|
+
const SelectDropdown = styled('div', selectDropdownAttrs)`
|
331
344
|
box-sizing: border-box;
|
332
345
|
z-index: ${(props) => (props.isActive ? '2' : '99999')};
|
333
346
|
position: absolute;
|
334
347
|
top: ${(props) =>
|
335
|
-
|
348
|
+
props.noRelative ? 'auto' : props.dropdownPosition?.top + 'px'};
|
336
349
|
left: ${(props) => props.dropdownPosition?.left}px;
|
337
350
|
border: ${BORDER_WIDTH} solid ${(props) => props.theme.colors.grey4};
|
338
351
|
border-radius: 4px;
|
@@ -347,36 +360,36 @@ const selectDropdown = styled('div', selectDropdownAttrs)`
|
|
347
360
|
? props.minWidth
|
348
361
|
: props.optionWidth
|
349
362
|
? props.optionWidth
|
350
|
-
|
363
|
+
: '100%'};
|
351
364
|
background-color: ${(props) =>
|
352
365
|
props.theme.colors[props.bgColor]
|
353
366
|
? props.theme.colors[props.bgColor]
|
354
|
-
|
367
|
+
: props.bgColor};
|
355
368
|
color: ${(props) =>
|
356
369
|
props.theme.colors[props.fontColor]
|
357
370
|
? props.theme.colors[props.fontColor]
|
358
|
-
|
371
|
+
: props.fontColor};
|
359
372
|
max-height: 300px;
|
360
373
|
overflow-y: auto;
|
361
374
|
& > div[data-value='${(props) => props.hoveredValue}'] {
|
362
375
|
background-color: ${(props) =>
|
363
376
|
props.theme.colors[props.hoveredBgColor]
|
364
377
|
? props.theme.colors[props.hoveredBgColor]
|
365
|
-
|
378
|
+
: props.hoveredBgColor};
|
366
379
|
}
|
367
380
|
font-size: ${(props) => props.fontSize};
|
368
381
|
`
|
369
|
-
selectDropdown.emits = ['option-hovered', 'option-selected']
|
370
|
-
const DropdownAttrs = { noRelative: Boolean }
|
371
|
-
const DropdownWrapper = styled('div', DropdownAttrs)`
|
382
|
+
selectDropdown.emits = ['option-hovered', 'option-selected']
|
383
|
+
const DropdownAttrs = { noRelative: Boolean }
|
384
|
+
const DropdownWrapper = styled('div', DropdownAttrs)`
|
372
385
|
position: ${(props) => (props.noRelative ? 'static' : 'relative')};
|
373
386
|
`
|
374
|
-
const inputAttrs = {
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
}
|
379
|
-
const InputWrapper = styled('div', inputAttrs)`
|
387
|
+
const inputAttrs = {
|
388
|
+
alignItems: String,
|
389
|
+
hasLabel: Boolean,
|
390
|
+
noRelative: Boolean
|
391
|
+
}
|
392
|
+
const InputWrapper = styled('div', inputAttrs)`
|
380
393
|
position: ${(props) => (props.noRelative ? 'static' : 'relative')};
|
381
394
|
display: grid;
|
382
395
|
width: 100%;
|
@@ -384,502 +397,502 @@ const InputWrapper = styled('div', inputAttrs)`
|
|
384
397
|
align-items: center;
|
385
398
|
gap: 8px;
|
386
399
|
grid-template-columns: ${(props) =>
|
387
|
-
|
400
|
+
props.alignItems === 'vertical' || !props.hasLabel ? '1fr' : 'auto 1fr'};
|
388
401
|
`
|
389
402
|
|
390
|
-
const DROPDOWN_HEIGHT_OFFSET = 4
|
391
|
-
const DROPDOWN_TOP_OFFSET = 21
|
392
|
-
const MIN_OPTION_LENGTH = 5
|
403
|
+
const DROPDOWN_HEIGHT_OFFSET = 4
|
404
|
+
const DROPDOWN_TOP_OFFSET = 21
|
405
|
+
const MIN_OPTION_LENGTH = 5
|
393
406
|
|
394
|
-
const DROPDOWN_MENU_POSITIONS = {
|
395
|
-
|
396
|
-
|
397
|
-
}
|
407
|
+
const DROPDOWN_MENU_POSITIONS = {
|
408
|
+
Automatic: 'automatic',
|
409
|
+
Bottom: 'bottom'
|
410
|
+
}
|
398
411
|
|
399
|
-
export default {
|
400
|
-
|
412
|
+
export default {
|
413
|
+
name: 'RCselect',
|
401
414
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
required: false,
|
420
|
-
default: false
|
421
|
-
},
|
422
|
-
labelDataId: {
|
423
|
-
required: false,
|
424
|
-
default: ''
|
425
|
-
},
|
426
|
-
infoTextMessage: {
|
427
|
-
required: false
|
428
|
-
},
|
429
|
-
selectWidth: {
|
430
|
-
type: String,
|
431
|
-
required: false,
|
432
|
-
default: '100%'
|
433
|
-
},
|
434
|
-
minWidth: {
|
435
|
-
required: false
|
436
|
-
},
|
437
|
-
maxWidth: {
|
438
|
-
required: false
|
439
|
-
},
|
440
|
-
selectHeight: {
|
441
|
-
type: String,
|
442
|
-
required: false,
|
443
|
-
default: null
|
415
|
+
components: {
|
416
|
+
SelectButton,
|
417
|
+
SelectButtonWrapper,
|
418
|
+
SelectDropdown,
|
419
|
+
Container,
|
420
|
+
InputLabel,
|
421
|
+
LabelWrapper,
|
422
|
+
OptionalLabel,
|
423
|
+
InfoText,
|
424
|
+
InputWrapper,
|
425
|
+
DropdownWrapper,
|
426
|
+
RCIcon,
|
427
|
+
Caret,
|
428
|
+
Selector,
|
429
|
+
InputText,
|
430
|
+
Teleport,
|
431
|
+
DraggableInputHandle
|
444
432
|
},
|
445
|
-
height: {
|
446
|
-
required: false,
|
447
|
-
default: null
|
448
|
-
},
|
449
|
-
selectMinHeight: {
|
450
|
-
required: false,
|
451
|
-
default: '36px'
|
452
|
-
},
|
453
|
-
optionWidth: {
|
454
|
-
required: false,
|
455
|
-
default: null
|
456
|
-
},
|
457
|
-
hoverDropdown: {
|
458
|
-
required: false,
|
459
|
-
default: false
|
460
|
-
},
|
461
|
-
dropdownAutoClose: {
|
462
|
-
required: false,
|
463
|
-
default: false
|
464
|
-
},
|
465
|
-
alignItems: {
|
466
|
-
required: false,
|
467
|
-
default: 'horizontal'
|
468
|
-
},
|
469
|
-
buttonBgColor: {
|
470
|
-
required: false
|
471
|
-
},
|
472
|
-
buttonFontColor: {
|
473
|
-
required: false
|
474
|
-
},
|
475
|
-
dropdownBgColor: {
|
476
|
-
required: false,
|
477
|
-
default: 'grey5'
|
478
|
-
},
|
479
|
-
dropdownFontColor: {
|
480
|
-
required: false
|
481
|
-
},
|
482
|
-
dropDownArrowVisible: {
|
483
|
-
required: false,
|
484
|
-
default: true
|
485
|
-
},
|
486
|
-
caretColor: {
|
487
|
-
required: false
|
488
|
-
},
|
489
|
-
labelFontColor: {
|
490
|
-
required: false
|
491
|
-
},
|
492
|
-
colorMode: {
|
493
|
-
required: false,
|
494
|
-
default: 'light'
|
495
|
-
},
|
496
|
-
isSearchable: {
|
497
|
-
required: false,
|
498
|
-
default: true
|
499
|
-
},
|
500
|
-
hasError: {
|
501
|
-
required: false,
|
502
|
-
default: false
|
503
|
-
},
|
504
|
-
disabled: {
|
505
|
-
required: false,
|
506
|
-
default: false
|
507
|
-
},
|
508
|
-
isAutoSearch: {
|
509
|
-
required: false,
|
510
|
-
default: true
|
511
|
-
},
|
512
|
-
showBorder: {
|
513
|
-
required: false,
|
514
|
-
default: true
|
515
|
-
},
|
516
|
-
infoTextSize: {
|
517
|
-
required: false,
|
518
|
-
default: '14px'
|
519
|
-
},
|
520
|
-
dataId: {
|
521
|
-
type: String,
|
522
|
-
default: ''
|
523
|
-
},
|
524
|
-
hasSelectButtonPadding: {
|
525
|
-
type: Boolean,
|
526
|
-
default: true
|
527
|
-
},
|
528
|
-
isDraggable: {
|
529
|
-
type: Boolean,
|
530
|
-
default: false
|
531
|
-
},
|
532
|
-
leftPadding: {
|
533
|
-
type: String,
|
534
|
-
default: '15px'
|
535
|
-
},
|
536
|
-
tablePaddingLeft: {
|
537
|
-
required: false
|
538
|
-
},
|
539
|
-
showDisabledBackground: {
|
540
|
-
required: false,
|
541
|
-
default: true
|
542
|
-
},
|
543
|
-
minOptionLength: {
|
544
|
-
type: Number,
|
545
|
-
default: MIN_OPTION_LENGTH
|
546
|
-
},
|
547
|
-
dropdownMenuPosition: {
|
548
|
-
type: String,
|
549
|
-
default: DROPDOWN_MENU_POSITIONS.Automatic // options: ['automatic', bottom]
|
550
|
-
}
|
551
|
-
},
|
552
|
-
|
553
|
-
components: {
|
554
|
-
selectButton,
|
555
|
-
SelectButtonWrapper,
|
556
|
-
selectDropdown,
|
557
|
-
Container,
|
558
|
-
InputLabel,
|
559
|
-
LabelWrapper,
|
560
|
-
optionalLabel,
|
561
|
-
InfoText,
|
562
|
-
InputWrapper,
|
563
|
-
DropdownWrapper,
|
564
|
-
icon,
|
565
|
-
Caret,
|
566
|
-
Selector,
|
567
|
-
inputText,
|
568
|
-
Teleport,
|
569
|
-
draggableInputHandle
|
570
|
-
},
|
571
433
|
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
},
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
}
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
434
|
+
props: {
|
435
|
+
value: {
|
436
|
+
required: false,
|
437
|
+
default: null
|
438
|
+
},
|
439
|
+
fontSize: {
|
440
|
+
required: false,
|
441
|
+
default: '13px'
|
442
|
+
},
|
443
|
+
noRelative: {
|
444
|
+
required: false,
|
445
|
+
default: false
|
446
|
+
},
|
447
|
+
label: {
|
448
|
+
required: false
|
449
|
+
},
|
450
|
+
labelOptional: {
|
451
|
+
required: false,
|
452
|
+
default: false
|
453
|
+
},
|
454
|
+
labelDataId: {
|
455
|
+
required: false,
|
456
|
+
default: ''
|
457
|
+
},
|
458
|
+
infoTextMessage: {
|
459
|
+
required: false
|
460
|
+
},
|
461
|
+
selectWidth: {
|
462
|
+
type: String,
|
463
|
+
required: false,
|
464
|
+
default: '100%'
|
465
|
+
},
|
466
|
+
minWidth: {
|
467
|
+
required: false
|
468
|
+
},
|
469
|
+
maxWidth: {
|
470
|
+
required: false
|
471
|
+
},
|
472
|
+
selectHeight: {
|
473
|
+
type: String,
|
474
|
+
required: false,
|
475
|
+
default: null
|
476
|
+
},
|
477
|
+
height: {
|
478
|
+
required: false,
|
479
|
+
default: null
|
480
|
+
},
|
481
|
+
selectMinHeight: {
|
482
|
+
required: false,
|
483
|
+
default: '36px'
|
484
|
+
},
|
485
|
+
optionWidth: {
|
486
|
+
required: false,
|
487
|
+
default: null
|
488
|
+
},
|
489
|
+
hoverDropdown: {
|
490
|
+
required: false,
|
491
|
+
default: false
|
492
|
+
},
|
493
|
+
dropdownAutoClose: {
|
494
|
+
required: false,
|
495
|
+
default: false
|
496
|
+
},
|
497
|
+
alignItems: {
|
498
|
+
required: false,
|
499
|
+
default: 'horizontal'
|
500
|
+
},
|
501
|
+
buttonBgColor: {
|
502
|
+
required: false
|
503
|
+
},
|
504
|
+
buttonFontColor: {
|
505
|
+
required: false
|
506
|
+
},
|
507
|
+
dropdownBgColor: {
|
508
|
+
required: false,
|
509
|
+
default: 'grey5'
|
510
|
+
},
|
511
|
+
dropdownFontColor: {
|
512
|
+
required: false
|
513
|
+
},
|
514
|
+
dropDownArrowVisible: {
|
515
|
+
required: false,
|
516
|
+
default: true
|
517
|
+
},
|
518
|
+
caretColor: {
|
519
|
+
required: false
|
520
|
+
},
|
521
|
+
labelFontColor: {
|
522
|
+
required: false
|
523
|
+
},
|
524
|
+
colorMode: {
|
525
|
+
required: false,
|
526
|
+
default: 'light'
|
527
|
+
},
|
528
|
+
isSearchable: {
|
529
|
+
required: false,
|
530
|
+
default: true
|
531
|
+
},
|
532
|
+
hasError: {
|
533
|
+
required: false,
|
534
|
+
default: false
|
535
|
+
},
|
536
|
+
disabled: {
|
537
|
+
required: false,
|
538
|
+
default: false
|
539
|
+
},
|
540
|
+
isAutoSearch: {
|
541
|
+
required: false,
|
542
|
+
default: true
|
543
|
+
},
|
544
|
+
showBorder: {
|
545
|
+
required: false,
|
546
|
+
default: true
|
547
|
+
},
|
548
|
+
infoTextSize: {
|
549
|
+
required: false,
|
550
|
+
default: '14px'
|
551
|
+
},
|
552
|
+
dataId: {
|
553
|
+
type: String,
|
554
|
+
default: ''
|
555
|
+
},
|
556
|
+
hasSelectButtonPadding: {
|
557
|
+
type: Boolean,
|
558
|
+
default: true
|
559
|
+
},
|
560
|
+
isDraggable: {
|
561
|
+
type: Boolean,
|
562
|
+
default: false
|
563
|
+
},
|
564
|
+
leftPadding: {
|
565
|
+
type: String,
|
566
|
+
default: '15px'
|
567
|
+
},
|
568
|
+
tablePaddingLeft: {
|
569
|
+
required: false
|
570
|
+
},
|
571
|
+
showDisabledBackground: {
|
572
|
+
required: false,
|
573
|
+
default: true
|
574
|
+
},
|
575
|
+
minOptionLength: {
|
576
|
+
type: Number,
|
577
|
+
default: MIN_OPTION_LENGTH
|
578
|
+
},
|
579
|
+
dropdownMenuPosition: {
|
580
|
+
type: String,
|
581
|
+
default: DROPDOWN_MENU_POSITIONS.Automatic // options: ['automatic', bottom]
|
646
582
|
}
|
647
583
|
},
|
648
|
-
|
649
|
-
|
650
|
-
|
584
|
+
|
585
|
+
data() {
|
586
|
+
return {
|
587
|
+
selectedValue: null,
|
588
|
+
paddingLeft: this.isDraggable ? '30px' : this.leftPadding,
|
589
|
+
isDropdownOpen: false,
|
590
|
+
isActive: false,
|
591
|
+
textSearch: '',
|
592
|
+
hoveredIndex: 0,
|
593
|
+
isClickOutsideActive: false,
|
594
|
+
dropdownPosition: {
|
595
|
+
left: null,
|
596
|
+
top: null
|
597
|
+
},
|
598
|
+
dropdownWidth: null,
|
599
|
+
hoveredValue: null
|
651
600
|
}
|
652
601
|
},
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
el.style.display = 'none'
|
660
|
-
|
661
|
-
return
|
602
|
+
computed: {
|
603
|
+
optionLength() {
|
604
|
+
if (this.isDropdownOpen) {
|
605
|
+
return this.$refs.dropdown.$el.childElementCount > 1
|
606
|
+
? this.$refs.dropdown.$el.childElementCount
|
607
|
+
: this.$refs.dropdown.$el.children[0].childElementCount
|
662
608
|
}
|
663
609
|
|
664
|
-
|
665
|
-
}
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
) {
|
678
|
-
return
|
679
|
-
} else {
|
680
|
-
this.closeDropdown()
|
681
|
-
}
|
682
|
-
},
|
683
|
-
onKeyDown(e) {
|
684
|
-
if (e.key == 'ArrowDown') {
|
685
|
-
this.onArrowPress(1)
|
686
|
-
} else if (e.key == 'ArrowUp') {
|
687
|
-
this.onArrowPress(-1)
|
688
|
-
} else if (e.key == 'Enter') {
|
689
|
-
const optionHoveredComponent = [...this.$refs.dropdown.$el.children][
|
690
|
-
(this.hoveredIndex - 1 + this.optionLength) % this.optionLength
|
691
|
-
]
|
692
|
-
this.optionSelected(optionHoveredComponent.$el.dataset.value)
|
693
|
-
}
|
694
|
-
},
|
695
|
-
// If some part of the dropdown menu is outside viewport of the bottom of the screen,
|
696
|
-
// we need to offset it and display it at the top of the select dropdown instead
|
697
|
-
async getDropdownPosition() {
|
698
|
-
if (
|
699
|
-
!this.$refs.dropdownWrapperRef ||
|
700
|
-
!this.$refs.select ||
|
701
|
-
!this.$refs.dropdown
|
702
|
-
) {
|
703
|
-
return
|
704
|
-
}
|
705
|
-
await this.$nextTick()
|
706
|
-
const isDisplayedAtBottom = await this.generateDropdownPosition()
|
707
|
-
// If the dropdown menu is going to be displayed at the bottom,
|
708
|
-
// we need reverify its position after a dom update (nextTick)
|
709
|
-
await this.$nextTick()
|
710
|
-
if (isDisplayedAtBottom) this.generateDropdownPosition()
|
711
|
-
},
|
712
|
-
async generateDropdownPosition() {
|
713
|
-
const isDropdownNotCompletelyVisible =
|
714
|
-
await this.isBottomOfDropdownOutOfViewport()
|
715
|
-
const dropdownWrapperEl = this.$refs.dropdownWrapperRef.$el
|
716
|
-
const selectButtonHeight = this.$refs.select.$el.clientHeight
|
717
|
-
const dropdownHeight = this.$refs.dropdown.$el.clientHeight
|
718
|
-
const dropdownWrapperRelativeHeight =
|
719
|
-
dropdownWrapperEl.getBoundingClientRect().top +
|
720
|
-
window.scrollY +
|
721
|
-
DROPDOWN_HEIGHT_OFFSET
|
610
|
+
return 0
|
611
|
+
},
|
612
|
+
isSearchBarVisible() {
|
613
|
+
return (
|
614
|
+
this.isSearchable &&
|
615
|
+
this.optionLength >= this.minOptionLength &&
|
616
|
+
this.isDropdownOpen
|
617
|
+
)
|
618
|
+
},
|
619
|
+
computedWidth() {
|
620
|
+
function removePX(item) {
|
621
|
+
return Number(item.replace('px', ''))
|
622
|
+
}
|
722
623
|
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
dropdownHeight -
|
730
|
-
selectButtonHeight -
|
731
|
-
DROPDOWN_TOP_OFFSET
|
732
|
-
const left = this.dropdownPosition.left
|
733
|
-
? this.dropdownPosition.left
|
734
|
-
: dropdownWrapperEl.getBoundingClientRect().left + window.scrollX
|
624
|
+
return this.selectWidth === '100%'
|
625
|
+
? '100%'
|
626
|
+
: removePX(this.selectWidth) - removePX(CARET_WIDTH) + 'px'
|
627
|
+
},
|
628
|
+
getOptionWidth() {
|
629
|
+
if (this.optionWidth) return this.optionWidth
|
735
630
|
|
736
|
-
|
631
|
+
return this.dropdownWidth
|
632
|
+
},
|
633
|
+
isSelectDropdownShown() {
|
634
|
+
return (
|
635
|
+
this.isDropdownOpen &&
|
636
|
+
this.dropdownPosition.left !== null &&
|
637
|
+
(!this.isSearchable || this.isSearchable)
|
638
|
+
)
|
639
|
+
},
|
640
|
+
isMobileDevice() {
|
641
|
+
const userAgent = navigator.userAgent || navigator.vendor || window.opera
|
642
|
+
const touchCapable =
|
643
|
+
'ontouchstart' in window ||
|
644
|
+
navigator.maxTouchPoints > 0 ||
|
645
|
+
navigator.msMaxTouchPoints > 0
|
737
646
|
|
738
|
-
|
647
|
+
return (
|
648
|
+
/Android/i.test(userAgent) ||
|
649
|
+
/iPad|iPhone|iPod/.test(userAgent) ||
|
650
|
+
(/Macintosh/.test(userAgent) && touchCapable) ||
|
651
|
+
/windows phone/i.test(userAgent)
|
652
|
+
)
|
653
|
+
}
|
739
654
|
},
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
) {
|
745
|
-
|
655
|
+
watch: {
|
656
|
+
value(val) {
|
657
|
+
this.selectedValue = val
|
658
|
+
},
|
659
|
+
async isDropdownOpen(val) {
|
660
|
+
if (val) {
|
661
|
+
this.$emit('on-dropdown-open')
|
662
|
+
setTimeout(() => {
|
663
|
+
this.isClickOutsideActive = true
|
664
|
+
}, 10)
|
665
|
+
await this.$nextTick()
|
666
|
+
this.handleSetDropdownOffet()
|
667
|
+
} else {
|
668
|
+
this.dropdownPosition.left = null
|
669
|
+
setTimeout(() => {
|
670
|
+
this.isClickOutsideActive = false
|
671
|
+
}, 10)
|
672
|
+
}
|
673
|
+
if (val && this.isSearchable) {
|
674
|
+
this.$nextTick(() => {
|
675
|
+
if (this.$refs.searchInput && !this.isMobileDevice) {
|
676
|
+
this.$refs.searchInput.$el.querySelector('input').focus()
|
677
|
+
}
|
678
|
+
})
|
679
|
+
}
|
746
680
|
}
|
681
|
+
},
|
682
|
+
mounted() {
|
683
|
+
this.observeDropdownHeight()
|
684
|
+
this.observeSelectWidth()
|
685
|
+
window.addEventListener('resize', this.handleSetDropdownOffet)
|
686
|
+
},
|
687
|
+
beforeMount() {
|
688
|
+
this.selectedValue = this.value
|
689
|
+
document.addEventListener('click', this.clickOutside)
|
690
|
+
this.getDropdownPosition()
|
691
|
+
window.removeEventListener('resize', this.handleSetDropdownOffet)
|
692
|
+
if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
|
693
|
+
if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
|
694
|
+
},
|
695
|
+
unmounted() {
|
696
|
+
document.removeEventListener('click', this.clickOutside)
|
697
|
+
},
|
698
|
+
methods: {
|
699
|
+
focus() {
|
700
|
+
this.isActive = true
|
701
|
+
},
|
702
|
+
blur(e) {
|
703
|
+
this.isActive = false
|
704
|
+
this.$emit('blur', e)
|
705
|
+
},
|
706
|
+
toggleDropdown() {
|
707
|
+
this.isDropdownOpen = !this.isDropdownOpen
|
708
|
+
},
|
709
|
+
toggleCaretDropdown() {
|
710
|
+
this.isDropdownOpen = !this.isDropdownOpen
|
711
|
+
},
|
712
|
+
closeDropdown() {
|
713
|
+
this.blur()
|
714
|
+
this.clearSearch()
|
715
|
+
this.isDropdownOpen = false
|
716
|
+
},
|
717
|
+
clearSearch() {
|
718
|
+
this.textSearch = ''
|
719
|
+
this.searchChange('')
|
720
|
+
},
|
721
|
+
optionSelected(e) {
|
722
|
+
this.selectedValue = e
|
723
|
+
this.closeDropdown()
|
724
|
+
this.blur()
|
725
|
+
this.$emit('input-change', e)
|
726
|
+
},
|
727
|
+
optionHovered(e) {
|
728
|
+
this.hoveredValue = e
|
729
|
+
},
|
730
|
+
mouseEnterHandler() {
|
731
|
+
if (this.hoverDropdown) {
|
732
|
+
this.focus()
|
733
|
+
this.isDropdownOpen = true
|
734
|
+
}
|
735
|
+
},
|
736
|
+
mouseLeaveHandler() {
|
737
|
+
if (this.hoverDropdown) {
|
738
|
+
this.blur()
|
739
|
+
}
|
740
|
+
},
|
741
|
+
optionLeave() {
|
742
|
+
if (this.dropdownAutoClose) {
|
743
|
+
this.isDropdownOpen = false
|
744
|
+
}
|
745
|
+
},
|
746
|
+
searchChange(value) {
|
747
|
+
this.textSearch = value
|
748
|
+
this.$emit('search-change', value)
|
749
|
+
const dropdownChildren = [...this.$refs.dropdown.$el.children]
|
750
|
+
dropdownChildren.forEach((el) => {
|
751
|
+
if (!el.textContent.toLowerCase().includes(value.toLowerCase())) {
|
752
|
+
el.style.display = 'none'
|
747
753
|
|
748
|
-
|
749
|
-
|
750
|
-
const windowHeight =
|
751
|
-
window.innerHeight || document.documentElement.clientHeight
|
752
|
-
|
753
|
-
if (windowHeight <= 650) return true
|
754
|
+
return
|
755
|
+
}
|
754
756
|
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
this.getDropdownWidth()
|
771
|
-
},
|
772
|
-
observeSelectWidth() {
|
773
|
-
if (!this.$refs.select) return
|
774
|
-
this.selectResizeObserver = new ResizeObserver(() =>
|
775
|
-
// eslint-disable-next-line vue/valid-next-tick
|
776
|
-
this.$nextTick(() => this.getDropdownWidth())
|
777
|
-
)
|
778
|
-
this.selectResizeObserver.observe(this.$refs.dropdown.$el)
|
779
|
-
},
|
780
|
-
async getDropdownWidth() {
|
781
|
-
if (!this.$refs.select) return
|
782
|
-
await this.$nextTick()
|
783
|
-
this.dropdownWidth = `${this.$refs.select.$el.clientWidth}px`
|
784
|
-
},
|
785
|
-
onArrowPress(dir) {
|
786
|
-
let newHoveredElem
|
787
|
-
const currentHoveredElem = this.$refs.dropdown.$el.querySelector(
|
788
|
-
`[data-value="${this.hoveredValue}"]`
|
789
|
-
)
|
790
|
-
if (currentHoveredElem) {
|
791
|
-
if (dir > 0) {
|
792
|
-
newHoveredElem = currentHoveredElem.nextElementSibling
|
757
|
+
el.style.display = 'inherit'
|
758
|
+
})
|
759
|
+
},
|
760
|
+
clickOutside(event) {
|
761
|
+
const dropdownRef = this.$refs.dropdown
|
762
|
+
// we need to prevent closing on selecting an option, because in the case of
|
763
|
+
// a disabled option, we don't want to close the dropdown
|
764
|
+
if (!this.isClickOutsideActive) return
|
765
|
+
if (
|
766
|
+
this.$refs.select.$el == event.target ||
|
767
|
+
this.$refs.select.$el.contains(event.target) ||
|
768
|
+
event.target.id === 'more-button' ||
|
769
|
+
event.target.parentNode === dropdownRef.$el
|
770
|
+
) {
|
771
|
+
return
|
793
772
|
} else {
|
794
|
-
|
773
|
+
this.closeDropdown()
|
774
|
+
}
|
775
|
+
},
|
776
|
+
onKeyDown(e) {
|
777
|
+
if (e.key == 'ArrowDown') {
|
778
|
+
this.onArrowPress(1)
|
779
|
+
} else if (e.key == 'ArrowUp') {
|
780
|
+
this.onArrowPress(-1)
|
781
|
+
} else if (e.key == 'Enter') {
|
782
|
+
const optionHoveredComponent = [...this.$refs.dropdown.$el.children][
|
783
|
+
(this.hoveredIndex - 1 + this.optionLength) % this.optionLength
|
784
|
+
]
|
785
|
+
this.optionSelected(optionHoveredComponent.$el.dataset.value)
|
795
786
|
}
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
787
|
+
},
|
788
|
+
// If some part of the dropdown menu is outside viewport of the bottom of the screen,
|
789
|
+
// we need to offset it and display it at the top of the select dropdown instead
|
790
|
+
async getDropdownPosition() {
|
791
|
+
if (
|
792
|
+
!this.$refs.dropdownWrapperRef ||
|
793
|
+
!this.$refs.select ||
|
794
|
+
!this.$refs.dropdown
|
795
|
+
) {
|
796
|
+
return
|
800
797
|
}
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
798
|
+
await this.$nextTick()
|
799
|
+
const isDisplayedAtBottom = await this.generateDropdownPosition()
|
800
|
+
// If the dropdown menu is going to be displayed at the bottom,
|
801
|
+
// we need reverify its position after a dom update (nextTick)
|
802
|
+
await this.$nextTick()
|
803
|
+
if (isDisplayedAtBottom) this.generateDropdownPosition()
|
804
|
+
},
|
805
|
+
async generateDropdownPosition() {
|
806
|
+
const isDropdownNotCompletelyVisible =
|
807
|
+
await this.isBottomOfDropdownOutOfViewport()
|
808
|
+
const dropdownWrapperEl = this.$refs.dropdownWrapperRef.$el
|
809
|
+
const selectButtonHeight = this.$refs.select.$el.clientHeight
|
810
|
+
const dropdownHeight = this.$refs.dropdown.$el.clientHeight
|
811
|
+
const dropdownWrapperRelativeHeight =
|
812
|
+
dropdownWrapperEl.getBoundingClientRect().top +
|
813
|
+
window.scrollY +
|
814
|
+
DROPDOWN_HEIGHT_OFFSET
|
811
815
|
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
}
|
816
|
+
const top =
|
817
|
+
isDropdownNotCompletelyVisible ||
|
818
|
+
(!isDropdownNotCompletelyVisible &&
|
819
|
+
this.dropdownMenuPosition === DROPDOWN_MENU_POSITIONS.Bottom)
|
820
|
+
? dropdownWrapperRelativeHeight
|
821
|
+
: dropdownWrapperRelativeHeight -
|
822
|
+
dropdownHeight -
|
823
|
+
selectButtonHeight -
|
824
|
+
DROPDOWN_TOP_OFFSET
|
825
|
+
const left = this.dropdownPosition.left
|
826
|
+
? this.dropdownPosition.left
|
827
|
+
: dropdownWrapperEl.getBoundingClientRect().left + window.scrollX
|
825
828
|
|
826
|
-
|
827
|
-
? '100%'
|
828
|
-
: removePX(this.selectWidth) - removePX(CARET_WIDTH) + 'px'
|
829
|
-
},
|
830
|
-
getOptionWidth() {
|
831
|
-
if (this.optionWidth) return this.optionWidth
|
829
|
+
this.dropdownPosition = { left: Math.floor(left), top: Math.floor(top) }
|
832
830
|
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
isMobileDevice() {
|
843
|
-
const userAgent = navigator.userAgent || navigator.vendor || window.opera
|
844
|
-
const touchCapable =
|
845
|
-
'ontouchstart' in window ||
|
846
|
-
navigator.maxTouchPoints > 0 ||
|
847
|
-
navigator.msMaxTouchPoints > 0
|
831
|
+
return isDropdownNotCompletelyVisible
|
832
|
+
},
|
833
|
+
async isBottomOfDropdownOutOfViewport() {
|
834
|
+
if (
|
835
|
+
!this.$refs.dropdown ||
|
836
|
+
this.dropdownMenuPosition === DROPDOWN_MENU_POSITIONS.Bottom
|
837
|
+
) {
|
838
|
+
return false
|
839
|
+
}
|
848
840
|
|
849
|
-
return (
|
850
|
-
/Android/i.test(userAgent) ||
|
851
|
-
/iPad|iPhone|iPod/.test(userAgent) ||
|
852
|
-
(/Macintosh/.test(userAgent) && touchCapable) ||
|
853
|
-
/windows phone/i.test(userAgent)
|
854
|
-
)
|
855
|
-
}
|
856
|
-
},
|
857
|
-
watch: {
|
858
|
-
value(val) {
|
859
|
-
this.selectedValue = val
|
860
|
-
},
|
861
|
-
async isDropdownOpen(val) {
|
862
|
-
if (val) {
|
863
|
-
this.$emit('on-dropdown-open')
|
864
|
-
setTimeout(() => {
|
865
|
-
this.isClickOutsideActive = true
|
866
|
-
}, 10)
|
867
841
|
await this.$nextTick()
|
868
|
-
this.
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
842
|
+
const rect = this.$refs.dropdown.$el.getBoundingClientRect()
|
843
|
+
const windowHeight =
|
844
|
+
window.innerHeight || document.documentElement.clientHeight
|
845
|
+
|
846
|
+
if (windowHeight <= 650) return true
|
847
|
+
|
848
|
+
// using Math.floor because the offsets may contain decimals we are not going to consider here
|
849
|
+
return Math.floor(rect.top) + Math.floor(rect.height) <= windowHeight
|
850
|
+
},
|
851
|
+
observeDropdownHeight() {
|
852
|
+
if (!this.$refs.dropdown) return
|
853
|
+
this.dropdownResizeObserver = new ResizeObserver(() => {
|
854
|
+
this.$nextTick(() => this.getDropdownPosition())
|
880
855
|
})
|
856
|
+
this.dropdownResizeObserver.observe(this.$refs.dropdown.$el)
|
857
|
+
},
|
858
|
+
handleSetDropdownOffet() {
|
859
|
+
if (!this.$refs.select) return
|
860
|
+
this.dropdownPosition.left = Math.floor(
|
861
|
+
this.$refs.select.$el.getBoundingClientRect().left
|
862
|
+
)
|
863
|
+
this.getDropdownWidth()
|
864
|
+
},
|
865
|
+
observeSelectWidth() {
|
866
|
+
if (!this.$refs.select) return
|
867
|
+
this.selectResizeObserver = new ResizeObserver(() =>
|
868
|
+
// eslint-disable-next-line vue/valid-next-tick
|
869
|
+
this.$nextTick(() => this.getDropdownWidth())
|
870
|
+
)
|
871
|
+
this.selectResizeObserver.observe(this.$refs.dropdown.$el)
|
872
|
+
},
|
873
|
+
async getDropdownWidth() {
|
874
|
+
if (!this.$refs.select) return
|
875
|
+
await this.$nextTick()
|
876
|
+
this.dropdownWidth = `${this.$refs.select.$el.clientWidth}px`
|
877
|
+
},
|
878
|
+
onArrowPress(dir) {
|
879
|
+
let newHoveredElem
|
880
|
+
const currentHoveredElem = this.$refs.dropdown.$el.querySelector(
|
881
|
+
`[data-value="${this.hoveredValue}"]`
|
882
|
+
)
|
883
|
+
if (currentHoveredElem) {
|
884
|
+
if (dir > 0) {
|
885
|
+
newHoveredElem = currentHoveredElem.nextElementSibling
|
886
|
+
} else {
|
887
|
+
newHoveredElem = currentHoveredElem.previousElementSibling
|
888
|
+
}
|
889
|
+
if (newHoveredElem) {
|
890
|
+
this.hoveredValue = newHoveredElem.getAttribute('data-value')
|
891
|
+
const topPos = newHoveredElem.offsetTop
|
892
|
+
this.$refs.dropdown.$el.scrollTop = topPos
|
893
|
+
}
|
894
|
+
}
|
881
895
|
}
|
882
896
|
}
|
883
897
|
}
|
884
|
-
}
|
885
898
|
</script>
|