@eturnity/eturnity_reusable_components 1.2.34-3d-master.5 → 1.2.34-3d-master.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/App.vue
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
<page-container>
|
4
4
|
<br />
|
5
5
|
|
6
|
-
<modal v-if="
|
6
|
+
<modal v-if="true" backdrop="dark" :isLoading="false" :isOpen="true">
|
7
7
|
|
8
8
|
<div :style="{padding:'50px'}">
|
9
9
|
|
@@ -53,18 +53,16 @@
|
|
53
53
|
alignItems="vertical"
|
54
54
|
colorMode="dark"
|
55
55
|
@input-change="value=$event"
|
56
|
+
@search-change="searchValue=$event"
|
56
57
|
>
|
57
58
|
<template #selector="{selectedValue}">
|
58
59
|
value selected: {{selectedValue}}
|
59
60
|
</template>
|
60
61
|
<template #dropdown>
|
61
|
-
<Option value="
|
62
|
-
<Option value="2">value two</Option>
|
63
|
-
<Option value="3">value three</Option>
|
64
|
-
<Option value="4">value four</Option>
|
62
|
+
<Option v-for="opt in filteredOptionList" :key="opt.id" :value="opt.val">{{ opt.lookFor }}</Option>
|
65
63
|
</template>
|
66
64
|
</Select>
|
67
|
-
|
65
|
+
{{filteredOptionList }}
|
68
66
|
</div>
|
69
67
|
</modal>
|
70
68
|
<iconCollection/>
|
@@ -110,7 +108,19 @@ export default {
|
|
110
108
|
return {
|
111
109
|
value:42,
|
112
110
|
value2:42,
|
113
|
-
companyName:"toto"
|
111
|
+
companyName:"toto",
|
112
|
+
optionList:[
|
113
|
+
{id:'a',val:'A',lookFor:'babababa'},
|
114
|
+
{id:'b',val:'B',lookFor:'abab'},
|
115
|
+
{id:'c',val:'C',lookFor:'ccc'},
|
116
|
+
{id:'d',val:'D',lookFor:'ddd'}
|
117
|
+
],
|
118
|
+
searchValue:""
|
119
|
+
}
|
120
|
+
},
|
121
|
+
computed:{
|
122
|
+
filteredOptionList(){
|
123
|
+
return this.optionList.filter(opt=>opt.lookFor.includes(this.searchValue))
|
114
124
|
}
|
115
125
|
},
|
116
126
|
methods: {
|
@@ -1,7 +1,6 @@
|
|
1
1
|
<template>
|
2
2
|
<Container
|
3
3
|
:selectWidth="selectWidth"
|
4
|
-
v-click-outside="closeDropdown"
|
5
4
|
@mouseenter="mouseEnterHandler"
|
6
5
|
@mouseleave="mouseLeaveHandler"
|
7
6
|
>
|
@@ -23,26 +22,44 @@
|
|
23
22
|
</label-wrapper>
|
24
23
|
<div>
|
25
24
|
<selectButton
|
26
|
-
|
25
|
+
ref="select"
|
26
|
+
@click="toggleDropdown"
|
27
27
|
:isActive="isActive"
|
28
28
|
:selectHeight="selectHeight"
|
29
29
|
:bgColor="buttonBgColor || colorMode=='dark'?'transparentBlack1':'white'"
|
30
30
|
:fontColor="buttonFontColor || colorMode=='dark'?'white':'black'"
|
31
|
-
|
31
|
+
@keydown.native="onKeyDown"
|
32
32
|
>
|
33
|
-
<
|
34
|
-
|
33
|
+
<inputText
|
34
|
+
v-if="isSearchBarVisible"
|
35
|
+
ref="searchInput"
|
36
|
+
tabindex="0"
|
37
|
+
:noBorder="true"
|
38
|
+
:inputHeight="selectHeight"
|
39
|
+
backgroundColor="transparent"
|
40
|
+
:fontColor="buttonFontColor || colorMode=='dark'?'white':'black'"
|
41
|
+
:value="textSearch"
|
42
|
+
@keydown.stop="onKeyDown"
|
43
|
+
@input-change="searchChange" />
|
44
|
+
<div v-else>
|
45
|
+
<slot name="selector" :selectedValue="selectedValue"></slot>
|
46
|
+
</div>
|
47
|
+
<Caret :isUp="isDropdownOpen" @click.stop="isSearchBarVisible ? closeDropdown() : toggleDropdown() " >
|
35
48
|
<icon name="arrow_up" size="12px" :color="caretColor || colorMode=='dark'?'white':'transparentBlack1'"/>
|
36
49
|
</Caret>
|
37
50
|
</selectButton>
|
38
51
|
<DropdownWrapper>
|
39
52
|
<selectDropdown
|
40
|
-
|
53
|
+
ref="dropdown"
|
54
|
+
v-show="isDropdownOpen"
|
55
|
+
:hoveredIndex="hoveredIndex"
|
41
56
|
:isActive="isActive"
|
42
57
|
:optionWidth="optionWidth"
|
43
58
|
:bgColor="dropdownBgColor || colorMode=='dark'?'black':'white'"
|
44
59
|
:fontColor="dropdownFontColor || colorMode=='dark'?'white':'black'"
|
45
|
-
|
60
|
+
:selectedValue="selectedValue"
|
61
|
+
@option-selected="optionSelected"
|
62
|
+
@option-hovered="optionHovered">
|
46
63
|
<slot name="dropdown"></slot>
|
47
64
|
</selectDropdown>
|
48
65
|
</DropdownWrapper>
|
@@ -74,7 +91,8 @@
|
|
74
91
|
import styled from 'vue-styled-components'
|
75
92
|
import InfoText from '../../infoText'
|
76
93
|
import icon from '../../icon'
|
77
|
-
|
94
|
+
import inputText from '../inputText'
|
95
|
+
|
78
96
|
const caretAttrs={isUp:Boolean}
|
79
97
|
const Caret=styled('div', caretAttrs)`
|
80
98
|
position:absolute;
|
@@ -112,18 +130,19 @@ const selectButton = styled('div',selectButtonAttrs)`
|
|
112
130
|
box-sizing: border-box;
|
113
131
|
border:1px solid red;
|
114
132
|
border-radius:4px;
|
115
|
-
padding:10px
|
133
|
+
padding:0px 10px;
|
116
134
|
text-align:left;
|
117
135
|
border-radius:4px;
|
118
136
|
min-height:36px;
|
119
|
-
display:
|
137
|
+
display: grid;
|
138
|
+
grid-template-columns:auto 40px;
|
120
139
|
align-items: center;
|
121
140
|
max-height:${props=>props.selectHeight};
|
122
141
|
border:1px solid ${(props)=>props.theme.colors.grey4}
|
123
142
|
background-color:${(props) => props.theme.colors[props.bgColor]?props.theme.colors[props.bgColor]:props.bgColor};
|
124
143
|
color:${(props) => props.theme.colors[props.fontColor]?props.theme.colors[props.fontColor]:props.fontColor};
|
125
144
|
`
|
126
|
-
const selectDropdownAttrs={bgColor:String,fontColor:String,selectWidth: String, optionWidth: String}
|
145
|
+
const selectDropdownAttrs={bgColor:String,fontColor:String,selectWidth: String, optionWidth: String,hoveredIndex:Number,selectedValue:Number | String}
|
127
146
|
const selectDropdown = styled('div',selectDropdownAttrs)`
|
128
147
|
box-sizing: border-box;
|
129
148
|
z-index:${props=>props.isActive?'2':'1'};
|
@@ -142,6 +161,12 @@ const selectDropdown = styled('div',selectDropdownAttrs)`
|
|
142
161
|
color:${(props) => props.theme.colors[props.fontColor]?props.theme.colors[props.fontColor]:props.fontColor};
|
143
162
|
max-height:300px;
|
144
163
|
overflow-y:auto;
|
164
|
+
& [data-value="${props=>props.selectedValue}"]{
|
165
|
+
backdrop-filter: brightness(1.4);
|
166
|
+
}
|
167
|
+
&>div:nth-child(${props=>props.hoveredIndex}){
|
168
|
+
backdrop-filter: brightness(1.2);
|
169
|
+
}
|
145
170
|
`
|
146
171
|
const DropdownWrapper=styled('div')`
|
147
172
|
position:relative;
|
@@ -217,6 +242,14 @@ const InputWrapper = styled('div', inputAttrs)`
|
|
217
242
|
colorMode:{
|
218
243
|
required:false,
|
219
244
|
default:'light'
|
245
|
+
},
|
246
|
+
isSearchable:{
|
247
|
+
required:false,
|
248
|
+
default:true
|
249
|
+
},
|
250
|
+
isAutoSearch:{
|
251
|
+
required:false,
|
252
|
+
default:true
|
220
253
|
}
|
221
254
|
},
|
222
255
|
|
@@ -230,7 +263,8 @@ const InputWrapper = styled('div', inputAttrs)`
|
|
230
263
|
InputWrapper,
|
231
264
|
DropdownWrapper,
|
232
265
|
icon,
|
233
|
-
Caret
|
266
|
+
Caret,
|
267
|
+
inputText
|
234
268
|
},
|
235
269
|
|
236
270
|
data() {
|
@@ -238,9 +272,11 @@ const InputWrapper = styled('div', inputAttrs)`
|
|
238
272
|
selectedValue: null,
|
239
273
|
isDropdownOpen:false,
|
240
274
|
isActive:false,
|
275
|
+
textSearch:"",
|
276
|
+
hoveredIndex:0,
|
241
277
|
}
|
242
278
|
},
|
243
|
-
|
279
|
+
mounted(){
|
244
280
|
this.selectedValue=this.value
|
245
281
|
},
|
246
282
|
methods:{
|
@@ -250,13 +286,25 @@ const InputWrapper = styled('div', inputAttrs)`
|
|
250
286
|
blur(){
|
251
287
|
this.isActive=false
|
252
288
|
},
|
253
|
-
toggleDropdown(){
|
254
|
-
this.
|
289
|
+
toggleDropdown(e){
|
290
|
+
if(this.isSearchBarVisible){return}
|
255
291
|
this.isDropdownOpen=!this.isDropdownOpen
|
292
|
+
if (this.isDropdownOpen) {
|
293
|
+
setTimeout(()=>document.addEventListener('click', this.clickOutside),10)
|
294
|
+
} else {
|
295
|
+
document.removeEventListener('click', this.clickOutside)
|
296
|
+
}
|
297
|
+
|
298
|
+
},
|
299
|
+
openDropdown(){
|
300
|
+
this.focus()
|
301
|
+
this.isDropdownOpen=true
|
302
|
+
setTimeout(()=>document.addEventListener('click', this.clickOutside),10)
|
256
303
|
},
|
257
304
|
closeDropdown(){
|
258
305
|
this.blur()
|
259
306
|
this.isDropdownOpen=false
|
307
|
+
document.removeEventListener('click', this.clickOutside)
|
260
308
|
},
|
261
309
|
optionSelected(e){
|
262
310
|
this.selectedValue=e
|
@@ -264,21 +312,74 @@ const InputWrapper = styled('div', inputAttrs)`
|
|
264
312
|
this.blur()
|
265
313
|
this.$emit('input-change',e)
|
266
314
|
},
|
315
|
+
optionHovered(e){
|
316
|
+
const optionElement=this.$el.querySelector(`[data-value="${e}"]`)
|
317
|
+
if(this.$refs.dropdown){
|
318
|
+
this.hoveredIndex=this.$refs.dropdown.$children.map(component=>component.$el).indexOf(optionElement)+1
|
319
|
+
}
|
320
|
+
},
|
267
321
|
mouseEnterHandler(){
|
268
|
-
this.focus()
|
269
322
|
if(this.hoverDropdown){
|
323
|
+
this.focus()
|
270
324
|
this.isDropdownOpen=true
|
271
325
|
}
|
272
326
|
},
|
273
327
|
mouseLeaveHandler(){
|
274
|
-
this.
|
328
|
+
if(this.hoverDropdown){
|
329
|
+
this.blur()
|
330
|
+
}
|
331
|
+
},
|
332
|
+
searchChange(value){
|
333
|
+
this.textSearch=value
|
334
|
+
this.$emit('search-change',value)
|
335
|
+
this.$refs.dropdown.$children.map(component=>component.$el).forEach((el=>{
|
336
|
+
if(!el.textContent.toLowerCase().includes(value.toLowerCase())){el.style.display='none'}else{el.style.display='inherit'}
|
337
|
+
}))
|
338
|
+
},
|
339
|
+
clickOutside(event) {
|
340
|
+
if (this.$el==event.target || this.$el.contains(event.target)) {
|
341
|
+
return
|
342
|
+
}
|
343
|
+
this.closeDropdown()
|
275
344
|
},
|
345
|
+
onKeyDown(e){
|
346
|
+
if(e.key=='ArrowDown'){
|
347
|
+
this.onArrowPress(1)
|
348
|
+
} else if(e.key=='ArrowUp'){
|
349
|
+
this.onArrowPress(-1)
|
350
|
+
} else if(e.key=='Enter'){
|
351
|
+
const optionHoveredComponent=this.$refs.dropdown.$children[(this.hoveredIndex-1+this.optionLength)%this.optionLength]
|
352
|
+
this.optionSelected(optionHoveredComponent.$el.dataset.value)
|
353
|
+
}
|
354
|
+
|
355
|
+
},
|
356
|
+
onArrowPress(dir){
|
357
|
+
this.hoveredIndex=((this.hoveredIndex+dir+this.optionLength-1)%this.optionLength)+1
|
358
|
+
const optionHoveredComponent=this.$refs.dropdown.$children[(this.hoveredIndex-1+this.optionLength)%this.optionLength]
|
359
|
+
const topPos = optionHoveredComponent.$el.offsetTop;
|
360
|
+
this.$refs.dropdown.$el.scrollTop = topPos;
|
361
|
+
}
|
276
362
|
},
|
277
363
|
computed: {
|
364
|
+
optionLength(){
|
365
|
+
if(this.isDropdownOpen){
|
366
|
+
return this.$refs.dropdown.$children.length
|
367
|
+
}else{
|
368
|
+
return 0
|
369
|
+
}
|
370
|
+
},
|
371
|
+
isSearchBarVisible(){
|
372
|
+
return this.isSearchable && this.optionLength>=5 && this.isDropdownOpen
|
373
|
+
}
|
278
374
|
},
|
279
375
|
watch:{
|
280
376
|
value(val){
|
281
377
|
this.selectedValue=val
|
378
|
+
},
|
379
|
+
isDropdownOpen(val){
|
380
|
+
if(val && this.isSearchable){
|
381
|
+
this.$nextTick(()=>{if(this.$refs.searchInput){this.$refs.searchInput.$el.querySelector('input').focus()}})
|
382
|
+
}
|
282
383
|
}
|
283
384
|
}
|
284
385
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<template>
|
2
|
-
<optionContainer :hoveredBgColor="hoveredBgColor || colorMode=='dark'?'#000000':'grey5'" @click="clickHandler">
|
2
|
+
<optionContainer :data-value="value" :hoveredBgColor="hoveredBgColor || colorMode=='dark'?'#000000':'grey5'" @click="clickHandler" @mouseover="hoverHandler">
|
3
3
|
<slot></slot>
|
4
4
|
</optionContainer>
|
5
5
|
</template>
|
@@ -48,6 +48,9 @@
|
|
48
48
|
methods:{
|
49
49
|
clickHandler(){
|
50
50
|
this.$parent.$emit('option-selected',this.value)
|
51
|
+
},
|
52
|
+
hoverHandler(){
|
53
|
+
this.$parent.$emit('option-hovered',this.value)
|
51
54
|
}
|
52
55
|
},
|
53
56
|
computed: {
|