@eturnity/eturnity_reusable_components 8.16.2--EPDM-14330.5 → 8.16.2--EPDM-14330.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 +1 -1
- package/src/assets/svgIcons/ac_power.svg +4 -0
- package/src/assets/svgIcons/arrow_long_left.svg +3 -0
- package/src/assets/svgIcons/arrow_long_right.svg +3 -0
- package/src/assets/svgIcons/chassis_ground_symbol.svg +27 -0
- package/src/assets/svgIcons/dc_power.svg +8 -0
- package/src/assets/svgIcons/double_arrow_long.svg +4 -0
- package/src/assets/svgIcons/ed_ac.svg +3 -0
- package/src/assets/svgIcons/ed_acgrid.svg +4 -0
- package/src/assets/svgIcons/ed_arrow_both.svg +7 -0
- package/src/assets/svgIcons/ed_arrow_left.svg +7 -0
- package/src/assets/svgIcons/ed_arrow_right.svg +7 -0
- package/src/assets/svgIcons/ed_battery.svg +10 -0
- package/src/assets/svgIcons/ed_batteryacinverter.svg +16 -0
- package/src/assets/svgIcons/ed_batteryintegratedinverter.svg +19 -0
- package/src/assets/svgIcons/ed_cirquitbreaker.svg +4 -0
- package/src/assets/svgIcons/ed_cirquitbreaker_magnetic.svg +6 -0
- package/src/assets/svgIcons/ed_cirquitbreaker_thermal.svg +4 -0
- package/src/assets/svgIcons/ed_cirquitbreaker_thermal_magnetic.svg +5 -0
- package/src/assets/svgIcons/ed_consumption.svg +3 -0
- package/src/assets/svgIcons/ed_dc.svg +6 -0
- package/src/assets/svgIcons/ed_disconnector.svg +4 -0
- package/src/assets/svgIcons/ed_disconnector_fuse.svg +4 -0
- package/src/assets/svgIcons/ed_disconnector_fuse_switch.svg +4 -0
- package/src/assets/svgIcons/ed_disconnector_loadbreak switch.svg +4 -0
- package/src/assets/svgIcons/ed_disconnector_switch.svg +4 -0
- package/src/assets/svgIcons/ed_disconnector_switch_auto_release.svg +5 -0
- package/src/assets/svgIcons/ed_energymanagement_rectangle.svg +3 -0
- package/src/assets/svgIcons/ed_evcharger.svg +19 -0
- package/src/assets/svgIcons/ed_flexiblecomponent_circle.svg +3 -0
- package/src/assets/svgIcons/ed_flexiblecomponent_square.svg +3 -0
- package/src/assets/svgIcons/ed_fuse.svg +3 -0
- package/src/assets/svgIcons/ed_ground.svg +5 -0
- package/src/assets/svgIcons/ed_heatpump.svg +4 -0
- package/src/assets/svgIcons/ed_icon_battery.svg +9 -0
- package/src/assets/svgIcons/ed_icon_circle.svg +3 -0
- package/src/assets/svgIcons/ed_icon_heatpump.svg +3 -0
- package/src/assets/svgIcons/ed_icon_inverter.svg +8 -0
- package/src/assets/svgIcons/ed_icon_optimizer.svg +11 -0
- package/src/assets/svgIcons/ed_integratedbatteryinverter.svg +10 -0
- package/src/assets/svgIcons/ed_inverter-blank.svg +3 -0
- package/src/assets/svgIcons/ed_mainsconnection.svg +3 -0
- package/src/assets/svgIcons/ed_meter_arrowleft.svg +4 -0
- package/src/assets/svgIcons/ed_meter_arrowright.svg +4 -0
- package/src/assets/svgIcons/ed_meter_bidirectional.svg +5 -0
- package/src/assets/svgIcons/ed_networkandsystemprotection_double.svg +14 -0
- package/src/assets/svgIcons/ed_networkandsystemprotection_single.svg +7 -0
- package/src/assets/svgIcons/ed_pvpanel.svg +7 -0
- package/src/assets/svgIcons/ed_rcd.svg +5 -0
- package/src/assets/svgIcons/ed_rcd_simple.svg +3 -0
- package/src/assets/svgIcons/ed_spd.svg +6 -0
- package/src/assets/svgIcons/ed_stringwithoptimizer.svg +33 -0
- package/src/assets/svgIcons/ed_stringwithoutoptimizer.svg +17 -0
- package/src/assets/svgIcons/ed_transformer.svg +3 -0
- package/src/assets/svgIcons/filter.svg +3 -0
- package/src/assets/svgIcons/ground_symbol.svg +28 -0
- package/src/assets/svgIcons/move_left.svg +3 -0
- package/src/assets/svgIcons/move_right.svg +3 -0
- package/src/assets/svgIcons/rectangle.svg +3 -0
- package/src/assets/svgIcons/refresh.svg +3 -0
- package/src/assets/svgIcons/text_icon.svg +3 -0
- package/src/assets/theme.js +17 -1
- package/src/components/banner/infoBanner/InfoBanner.spec.js +29 -42
- package/src/components/barchart/BottomFields.vue +253 -0
- package/src/components/barchart/ChartControls.vue +113 -0
- package/src/components/barchart/SelectionBox.vue +150 -0
- package/src/components/barchart/composables/index.js +5 -0
- package/src/components/barchart/composables/useAxisCalculations.js +104 -0
- package/src/components/barchart/composables/useChartData.js +114 -0
- package/src/components/barchart/composables/useChartScroll.js +61 -0
- package/src/components/barchart/composables/useSelection.js +75 -0
- package/src/components/barchart/composables/useTooltip.js +100 -0
- package/src/components/barchart/index.vue +385 -0
- package/src/components/barchart/styles/bottomFields.js +66 -0
- package/src/components/barchart/styles/chart.js +272 -0
- package/src/components/barchart/styles/chartControls.js +59 -0
- package/src/components/buttons/buttonIcon/index.vue +35 -1
- package/src/components/buttons/splitButtons/index.vue +86 -0
- package/src/components/collapsableInfoText/index.vue +2 -2
- package/src/components/errorMessage/errorMessage.spec.js +34 -0
- package/src/components/errorMessage/errorMessage.stories.js +35 -0
- package/src/components/filter/filterSettings.vue +2 -0
- package/src/components/filterComponent/viewFilter.vue +589 -0
- package/src/components/filterComponent/viewSettings.vue +63 -2
- package/src/components/filterComponent/viewSort.vue +18 -5
- package/src/components/icon/index.vue +32 -9
- package/src/components/infoText/index.vue +2 -2
- package/src/components/infoText/infoText.spec.js +6 -1
- package/src/components/inputs/inputNumber/index.vue +14 -2
- package/src/components/inputs/searchInput/index.vue +19 -3
- package/src/components/inputs/select/index.vue +108 -19
- package/src/components/inputs/select/option/index.vue +5 -0
- package/src/components/modals/actionModal/actionModal.spec.js +52 -0
- package/src/components/modals/actionModal/actionModal.stories.js +53 -0
- package/src/components/modals/actionModal/index.vue +6 -6
- package/src/components/modals/infoModal/index.vue +49 -19
- package/src/components/modals/infoModal/infoModal.spec.js +55 -0
- package/src/components/modals/infoModal/infoModal.stories.js +47 -0
- package/src/components/modals/modal/index.vue +16 -5
- package/src/components/pageSubtitle/PageSubtitle.stories.js +0 -1
- package/src/helpers/isObjectEqual.js +22 -0
- package/src/helpers/translateLang.js +95 -24
- package/src/main.js +1 -0
@@ -3,6 +3,7 @@
|
|
3
3
|
<ButtonIcon
|
4
4
|
class="button-icon"
|
5
5
|
icon-name="sorting"
|
6
|
+
:number-count="getNumberCount()"
|
6
7
|
:text="$gettext('sort')"
|
7
8
|
type="filter"
|
8
9
|
@click="toggleOptions"
|
@@ -22,6 +23,7 @@
|
|
22
23
|
class="sort-dropdown"
|
23
24
|
:dropdown-auto-close="false"
|
24
25
|
select-height="40px"
|
26
|
+
@click.stop
|
25
27
|
@input-change="
|
26
28
|
onSelectSort({
|
27
29
|
type: 'column',
|
@@ -52,6 +54,7 @@
|
|
52
54
|
class="sort-dropdown"
|
53
55
|
:dropdown-auto-close="false"
|
54
56
|
select-height="40px"
|
57
|
+
@click.stop
|
55
58
|
@input-change="
|
56
59
|
onSelectSort({
|
57
60
|
type: 'direction',
|
@@ -97,6 +100,7 @@
|
|
97
100
|
class="sort-dropdown"
|
98
101
|
:dropdown-auto-close="false"
|
99
102
|
select-height="40px"
|
103
|
+
@click.stop
|
100
104
|
@input-change="
|
101
105
|
onSelectSort({
|
102
106
|
type: 'column',
|
@@ -124,6 +128,7 @@
|
|
124
128
|
class="sort-dropdown"
|
125
129
|
:dropdown-auto-close="false"
|
126
130
|
select-height="40px"
|
131
|
+
@click.stop
|
127
132
|
@input-change="
|
128
133
|
onSelectSort({
|
129
134
|
type: 'direction',
|
@@ -267,17 +272,28 @@
|
|
267
272
|
handleClickOutside(event) {
|
268
273
|
const buttonIcon = this.$el.querySelector('.button-icon')
|
269
274
|
const boxContainer = this.$el.querySelector('.box-container')
|
270
|
-
const
|
275
|
+
const isClickInSelect =
|
276
|
+
event.target.closest('.sort-dropdown') ||
|
277
|
+
event.target.closest('.rc-select-dropdown') ||
|
278
|
+
event.target.closest('.select-button') ||
|
279
|
+
event.target.closest('.caret_dropdown')
|
271
280
|
|
272
281
|
if (
|
273
282
|
!buttonIcon.contains(event.target) &&
|
274
283
|
!boxContainer.contains(event.target) &&
|
275
|
-
!
|
284
|
+
!isClickInSelect
|
276
285
|
) {
|
277
286
|
this.isOptionsVisible = false
|
278
287
|
document.removeEventListener('click', this.handleClickOutside)
|
279
288
|
}
|
280
289
|
},
|
290
|
+
getNumberCount() {
|
291
|
+
return this.selectedSort.filter((item) => {
|
292
|
+
const hasColumn = !!item.column
|
293
|
+
const hasDirection = !!item.direction
|
294
|
+
return hasColumn && hasDirection
|
295
|
+
}).length
|
296
|
+
},
|
281
297
|
toggleOptions() {
|
282
298
|
this.isOptionsVisible = !this.isOptionsVisible
|
283
299
|
if (this.isOptionsVisible) {
|
@@ -287,7 +303,6 @@
|
|
287
303
|
}
|
288
304
|
},
|
289
305
|
getSelectedLabel({ type, value }) {
|
290
|
-
// debugger
|
291
306
|
if (!value) return
|
292
307
|
if (type === 'column') {
|
293
308
|
return this.sortOptions.find((option) => option.value === value).label
|
@@ -297,8 +312,6 @@
|
|
297
312
|
}
|
298
313
|
},
|
299
314
|
onSelectSort({ type, value, index }) {
|
300
|
-
console.log(type, value, index)
|
301
|
-
|
302
315
|
this.$emit('on-sort-change', {
|
303
316
|
type,
|
304
317
|
value,
|
@@ -3,13 +3,15 @@
|
|
3
3
|
:cursor="cursor"
|
4
4
|
data-test-id="icon_wrapper"
|
5
5
|
:disabled="disabled"
|
6
|
-
:
|
6
|
+
:height="height ? height : size"
|
7
|
+
:width="width ? width : size"
|
7
8
|
>
|
8
9
|
<IconImage
|
9
10
|
:animation="animation"
|
10
11
|
:background-color="backgroundColor"
|
11
12
|
:color="color"
|
12
13
|
data-test-id="icon_image"
|
14
|
+
:disable-hover="disableHover"
|
13
15
|
:fill-type="fillType"
|
14
16
|
:hovered-color="hoveredColor"
|
15
17
|
>
|
@@ -67,6 +69,16 @@
|
|
67
69
|
default: '30px',
|
68
70
|
type: String,
|
69
71
|
},
|
72
|
+
width: {
|
73
|
+
type: String,
|
74
|
+
required: false,
|
75
|
+
default: '',
|
76
|
+
},
|
77
|
+
height: {
|
78
|
+
type: String,
|
79
|
+
required: false,
|
80
|
+
default: '',
|
81
|
+
},
|
70
82
|
cursor: {
|
71
83
|
required: false,
|
72
84
|
default: null,
|
@@ -97,10 +109,15 @@
|
|
97
109
|
default: 'fill',
|
98
110
|
type: String,
|
99
111
|
},
|
112
|
+
disableHover: {
|
113
|
+
type: Boolean,
|
114
|
+
default: false,
|
115
|
+
},
|
100
116
|
})
|
101
117
|
|
102
118
|
const Wrapper = styled('div', {
|
103
|
-
|
119
|
+
height: String,
|
120
|
+
width: String,
|
104
121
|
disabled: Boolean,
|
105
122
|
cursor: String,
|
106
123
|
})`
|
@@ -108,10 +125,10 @@
|
|
108
125
|
position: relative;
|
109
126
|
align-content: center;
|
110
127
|
justify-content: center;
|
111
|
-
width: ${(props) => props.
|
112
|
-
height: ${(props) => props.
|
113
|
-
min-width: ${(props) => props.
|
114
|
-
min-height: ${(props) => props.
|
128
|
+
width: ${(props) => props.width};
|
129
|
+
height: ${(props) => props.height};
|
130
|
+
min-width: ${(props) => props.width};
|
131
|
+
min-height: ${(props) => props.height};
|
115
132
|
cursor: ${(props) => (props.disabled ? 'not-allowed' : props.cursor)};
|
116
133
|
line-height: 0;
|
117
134
|
`
|
@@ -152,6 +169,7 @@
|
|
152
169
|
hoveredColor: String,
|
153
170
|
animation: String,
|
154
171
|
fillType: String,
|
172
|
+
disableHover: Boolean,
|
155
173
|
}
|
156
174
|
const IconImage = styled('div', IconImageAttrs)`
|
157
175
|
animation: ${(props) => props.animation};
|
@@ -168,12 +186,17 @@
|
|
168
186
|
${({ theme, color, fillType }) =>
|
169
187
|
color && `${fillType}: ${theme.colors[color] || color};`}
|
170
188
|
}
|
171
|
-
|
172
|
-
|
189
|
+
${(props) =>
|
190
|
+
!props.disableHover &&
|
191
|
+
`
|
192
|
+
&:hover svg path:not(.fix) {
|
193
|
+
${`${props.fillType}: ${props.hoveredColor || props.color};`}
|
173
194
|
}
|
174
195
|
&:hover + div {
|
175
|
-
background-color: ${
|
196
|
+
background-color: ${props.hoveredColor};
|
176
197
|
}
|
198
|
+
`}
|
199
|
+
|
177
200
|
@keyframes fade {
|
178
201
|
50% {
|
179
202
|
opacity: 0.3;
|
@@ -46,7 +46,7 @@
|
|
46
46
|
</IconWrapper>
|
47
47
|
</div>
|
48
48
|
<Teleport v-if="isVisible" to="body">
|
49
|
-
<TextWrapper :style="wrapperStyle">
|
49
|
+
<TextWrapper data-test-id="info_text_wrapper" :style="wrapperStyle">
|
50
50
|
<TextOverlay
|
51
51
|
ref="infoBox"
|
52
52
|
:app-theme="appTheme"
|
@@ -137,7 +137,7 @@
|
|
137
137
|
`
|
138
138
|
|
139
139
|
const TextWrapper = styled('div')`
|
140
|
-
z-index:
|
140
|
+
z-index: 9999999999;
|
141
141
|
position: absolute;
|
142
142
|
`
|
143
143
|
|
@@ -29,6 +29,9 @@ describe('InfoText Component', () => {
|
|
29
29
|
provide: {
|
30
30
|
theme,
|
31
31
|
},
|
32
|
+
stubs: {
|
33
|
+
teleport: true
|
34
|
+
}
|
32
35
|
},
|
33
36
|
})
|
34
37
|
})
|
@@ -38,7 +41,6 @@ describe('InfoText Component', () => {
|
|
38
41
|
expect(wrapper.vm.text).toContain('default text')
|
39
42
|
expect(wrapper.vm.size).toContain('14px')
|
40
43
|
expect(wrapper.vm.infoPosition).toContain('bottom')
|
41
|
-
expect(wrapper.vm.alignArrow).toContain('center')
|
42
44
|
})
|
43
45
|
|
44
46
|
test('openTrigger prop is set to onClick', async () => {
|
@@ -48,8 +50,11 @@ describe('InfoText Component', () => {
|
|
48
50
|
expect(wrapper.find('[data-test-id="info_text_wrapper"]').exists()).toBe(
|
49
51
|
false
|
50
52
|
)
|
53
|
+
|
51
54
|
//should see text upon click
|
52
55
|
await wrapper.find('[data-test-id="infoText_trigger"]').trigger('click')
|
56
|
+
expect(wrapper.vm.isVisible).toBe(true)
|
57
|
+
|
53
58
|
expect(wrapper.find('[data-test-id="info_text_wrapper"]').exists()).toBe(
|
54
59
|
true
|
55
60
|
)
|
@@ -56,6 +56,7 @@
|
|
56
56
|
:min-width="minWidth"
|
57
57
|
:no-border="noBorder"
|
58
58
|
:placeholder="displayedPlaceholder"
|
59
|
+
:read-only="isReadOnly"
|
59
60
|
:show-arrow-controls="showArrowControls"
|
60
61
|
:show-linear-unit-name="showLinearUnitName"
|
61
62
|
:slot-size="slotSize"
|
@@ -163,6 +164,7 @@
|
|
163
164
|
// labelInfoAlign="left"
|
164
165
|
// :minNumber="0"
|
165
166
|
// fontColor="blue"
|
167
|
+
// :isReadOnly="true"
|
166
168
|
// colorMode="transparent" // Makes background transparent, border white, and font white
|
167
169
|
// >
|
168
170
|
//<template name=label><img>....</template>
|
@@ -202,6 +204,7 @@
|
|
202
204
|
showLinearUnitName: Boolean,
|
203
205
|
colorMode: String,
|
204
206
|
showArrowControls: Boolean,
|
207
|
+
readOnly: Boolean,
|
205
208
|
}
|
206
209
|
|
207
210
|
const Container = styled('div', inputProps)`
|
@@ -250,7 +253,8 @@
|
|
250
253
|
? '0 4px 4px 0'
|
251
254
|
: '4px'};
|
252
255
|
text-align: ${(props) => props.textAlign};
|
253
|
-
cursor: ${(props) =>
|
256
|
+
cursor: ${(props) =>
|
257
|
+
props.isDisabled || props.readOnly ? 'not-allowed' : 'auto'};
|
254
258
|
font-size: ${(props) => (props.fontSize ? props.fontSize : '13px')};
|
255
259
|
color: ${(props) =>
|
256
260
|
props.isError
|
@@ -263,7 +267,9 @@
|
|
263
267
|
? props.fontColor + ' !important'
|
264
268
|
: props.theme.colors.black};
|
265
269
|
background-color: ${(props) =>
|
266
|
-
props.
|
270
|
+
props.readOnly
|
271
|
+
? props.theme.semanticColors.grey[300]
|
272
|
+
: props.isDisabled
|
267
273
|
? props.colorMode === 'transparent'
|
268
274
|
? 'transparent'
|
269
275
|
: props.theme.colors.grey5
|
@@ -276,6 +282,8 @@
|
|
276
282
|
box-sizing: border-box;
|
277
283
|
opacity: ${(props) =>
|
278
284
|
props.isDisabled && props.colorMode === 'transparent' ? '0.4' : '1'};
|
285
|
+
pointer-events: ${(props) => (props.readOnly ? 'none' : 'auto')};
|
286
|
+
user-select: ${(props) => (props.readOnly ? 'none' : 'auto')};
|
279
287
|
|
280
288
|
&::placeholder {
|
281
289
|
color: ${(props) => props.theme.colors.grey2};
|
@@ -686,6 +694,10 @@
|
|
686
694
|
type: Boolean,
|
687
695
|
default: false,
|
688
696
|
},
|
697
|
+
isReadOnly: {
|
698
|
+
type: Boolean,
|
699
|
+
default: false,
|
700
|
+
},
|
689
701
|
},
|
690
702
|
data() {
|
691
703
|
return {
|
@@ -1,6 +1,10 @@
|
|
1
1
|
<template>
|
2
2
|
<Container :input-width="inputWidth">
|
3
|
-
<InputWrapper
|
3
|
+
<InputWrapper
|
4
|
+
:icon-color="iconColor"
|
5
|
+
:icon-position="iconPosition"
|
6
|
+
:is-full-height="isFullHeight"
|
7
|
+
>
|
4
8
|
<SearchIconSvg class="search-icn" />
|
5
9
|
<InputContainer
|
6
10
|
ref="inputElement"
|
@@ -11,6 +15,7 @@
|
|
11
15
|
:input-width="inputWidth"
|
12
16
|
:is-disabled="disabled"
|
13
17
|
:is-filter="isFilter"
|
18
|
+
:is-full-height="isFullHeight"
|
14
19
|
:placeholder="placeholder"
|
15
20
|
:value="value"
|
16
21
|
@input="onChangeHandler($event)"
|
@@ -41,6 +46,7 @@
|
|
41
46
|
isDisabled: Boolean,
|
42
47
|
inputWidth: String,
|
43
48
|
isFilter: Boolean,
|
49
|
+
isFullHeight: Boolean,
|
44
50
|
}
|
45
51
|
const Container = styled('div', inputAttrs)`
|
46
52
|
width: ${(props) => (props.inputWidth ? props.inputWidth : '100%')};
|
@@ -50,11 +56,12 @@
|
|
50
56
|
const InputContainer = styled('input', inputAttrs)`
|
51
57
|
border: 1px solid ${(props) => props.theme.colors.grey4};
|
52
58
|
padding: ${(props) =>
|
53
|
-
props.isFilter ? '
|
59
|
+
props.isFilter ? '8px 30px 8px 10px' : '11px 30px 11px 10px'};
|
54
60
|
border-radius: 4px;
|
55
61
|
font-size: 13px;
|
56
62
|
color: ${(props) => props.theme.colors.black};
|
57
63
|
width: ${(props) => (props.inputWidth ? props.inputWidth : '100%')};
|
64
|
+
height: ${(props) => (props.isFullHeight ? '100%' : 'auto')};
|
58
65
|
box-sizing: border-box;
|
59
66
|
cursor: ${(props) => (props.isDisabled ? 'not-allowed' : 'auto')};
|
60
67
|
background: ${(props) => props.theme.colors.white} !important;
|
@@ -67,9 +74,14 @@
|
|
67
74
|
}
|
68
75
|
`
|
69
76
|
|
70
|
-
const wrapperAttrs = {
|
77
|
+
const wrapperAttrs = {
|
78
|
+
iconColor: String,
|
79
|
+
iconPosition: String,
|
80
|
+
isFullHeight: Boolean,
|
81
|
+
}
|
71
82
|
const InputWrapper = styled('div', wrapperAttrs)`
|
72
83
|
position: relative;
|
84
|
+
height: ${(props) => (props.isFullHeight ? '100%' : 'auto')};
|
73
85
|
|
74
86
|
svg {
|
75
87
|
position: absolute;
|
@@ -142,6 +154,10 @@
|
|
142
154
|
type: String,
|
143
155
|
default: 'black',
|
144
156
|
},
|
157
|
+
isFullHeight: {
|
158
|
+
type: Boolean,
|
159
|
+
default: false,
|
160
|
+
},
|
145
161
|
},
|
146
162
|
emits: ['on-change'],
|
147
163
|
watch: {
|
@@ -109,11 +109,7 @@
|
|
109
109
|
>
|
110
110
|
<slot name="selector" :selected-value="selectedValue"></slot>
|
111
111
|
</Selector>
|
112
|
-
<Caret
|
113
|
-
class="caret_dropdown"
|
114
|
-
:color-mode="colorMode"
|
115
|
-
@click.stop="toggleCaretDropdown"
|
116
|
-
>
|
112
|
+
<Caret class="caret_dropdown" :color-mode="colorMode">
|
117
113
|
<Icon
|
118
114
|
v-if="isDropdownOpen"
|
119
115
|
:color="
|
@@ -137,17 +133,19 @@
|
|
137
133
|
</Caret>
|
138
134
|
</SelectButton>
|
139
135
|
<DropdownWrapper ref="dropdownWrapperRef" :no-relative="noRelative">
|
140
|
-
<
|
136
|
+
<Component
|
137
|
+
:is="shouldUseTeleport ? 'Teleport' : 'div'"
|
138
|
+
:to="shouldUseTeleport ? 'body' : undefined"
|
139
|
+
>
|
141
140
|
<SelectDropdown
|
142
141
|
v-show="isSelectDropdownShown"
|
143
142
|
ref="dropdown"
|
144
143
|
:bg-color="
|
145
|
-
|
146
|
-
colorMode == 'dark' ||
|
147
|
-
colorMode == 'transparent'
|
144
|
+
colorMode == 'dark' || colorMode == 'transparent'
|
148
145
|
? 'black'
|
149
146
|
: 'white'
|
150
147
|
"
|
148
|
+
class="rc-select-dropdown"
|
151
149
|
:dropdown-position="dropdownPosition"
|
152
150
|
:font-color="
|
153
151
|
dropdownFontColor ||
|
@@ -167,10 +165,22 @@
|
|
167
165
|
:hovered-index="hoveredIndex"
|
168
166
|
:hovered-value="hoveredValue"
|
169
167
|
:is-active="isActive"
|
168
|
+
:is-fixed-dropdown-position="isFixedDropdownPosition"
|
169
|
+
:is-parent-modal="isParentModal"
|
170
|
+
:is-teleport="shouldUseTeleport"
|
170
171
|
:min-width="minWidth"
|
171
172
|
:no-relative="noRelative"
|
172
173
|
:option-width="getOptionWidth"
|
173
174
|
:selected-value="selectedValue"
|
175
|
+
:style="
|
176
|
+
shouldUseTeleport
|
177
|
+
? {
|
178
|
+
transform: `translate(${dropdownPosition?.left}px, ${
|
179
|
+
noRelative ? 'auto' : `${dropdownPosition?.top}px`
|
180
|
+
})`,
|
181
|
+
}
|
182
|
+
: undefined
|
183
|
+
"
|
174
184
|
@click.stop
|
175
185
|
@mouseleave="optionLeave"
|
176
186
|
@option-hovered="optionHovered"
|
@@ -178,7 +188,7 @@
|
|
178
188
|
>
|
179
189
|
<slot name="dropdown"></slot>
|
180
190
|
</SelectDropdown>
|
181
|
-
</
|
191
|
+
</Component>
|
182
192
|
</DropdownWrapper>
|
183
193
|
</SelectButtonWrapper>
|
184
194
|
</InputWrapper>
|
@@ -209,7 +219,7 @@
|
|
209
219
|
// </template>
|
210
220
|
// </Select>
|
211
221
|
|
212
|
-
import { Teleport } from 'vue'
|
222
|
+
import { Teleport, inject } from 'vue'
|
213
223
|
import styled from 'vue3-styled-components'
|
214
224
|
import InfoText from '../../infoText'
|
215
225
|
import Icon from '../../icon'
|
@@ -393,14 +403,18 @@
|
|
393
403
|
selectedValue: Number | String,
|
394
404
|
noRelative: Boolean,
|
395
405
|
minWidth: String,
|
406
|
+
isParentModal: Boolean,
|
407
|
+
isFixedDropdownPosition: Boolean,
|
408
|
+
isTeleport: Boolean,
|
396
409
|
}
|
397
410
|
const SelectDropdown = styled('div', selectDropdownAttrs)`
|
398
411
|
box-sizing: border-box;
|
399
|
-
z-index: ${(props) =>
|
400
|
-
|
401
|
-
|
402
|
-
props.
|
403
|
-
|
412
|
+
z-index: ${(props) =>
|
413
|
+
props.isActive ? '2' : props.isParentModal ? '9999999' : '99999'};
|
414
|
+
position: ${(props) =>
|
415
|
+
props.isFixedDropdownPosition ? 'fixed' : 'absolute'};
|
416
|
+
top: ${(props) => (props.isTeleport ? '0px' : '4px')};
|
417
|
+
left: 0px;
|
404
418
|
border: ${BORDER_WIDTH} solid ${(props) => props.theme.colors.grey4};
|
405
419
|
border-radius: 4px;
|
406
420
|
display: flex;
|
@@ -648,6 +662,23 @@
|
|
648
662
|
type: String,
|
649
663
|
required: false,
|
650
664
|
},
|
665
|
+
isFixedDropdownPosition: {
|
666
|
+
type: Boolean,
|
667
|
+
required: false,
|
668
|
+
default: false,
|
669
|
+
},
|
670
|
+
shouldUseTeleport: {
|
671
|
+
type: Boolean,
|
672
|
+
required: false,
|
673
|
+
default: true,
|
674
|
+
},
|
675
|
+
},
|
676
|
+
setup() {
|
677
|
+
const modalRef = inject('modalRef')
|
678
|
+
|
679
|
+
return {
|
680
|
+
modalRef,
|
681
|
+
}
|
651
682
|
},
|
652
683
|
|
653
684
|
data() {
|
@@ -665,6 +696,10 @@
|
|
665
696
|
},
|
666
697
|
dropdownWidth: null,
|
667
698
|
hoveredValue: null,
|
699
|
+
isDisplayedAtBottom: true,
|
700
|
+
selectTopPosition: 0,
|
701
|
+
selectAndDropdownDistance: 0,
|
702
|
+
animationFrameId: null,
|
668
703
|
}
|
669
704
|
},
|
670
705
|
computed: {
|
@@ -722,6 +757,9 @@
|
|
722
757
|
/windows phone/i.test(userAgent)
|
723
758
|
)
|
724
759
|
},
|
760
|
+
isParentModal() {
|
761
|
+
return !!this.modalRef
|
762
|
+
},
|
725
763
|
},
|
726
764
|
watch: {
|
727
765
|
value(val) {
|
@@ -735,8 +773,13 @@
|
|
735
773
|
}, 10)
|
736
774
|
await this.$nextTick()
|
737
775
|
this.handleSetDropdownOffet()
|
776
|
+
if (!this.isFixedDropdownPosition) this.calculateSelectTopPosition()
|
738
777
|
} else {
|
739
778
|
this.dropdownPosition.left = null
|
779
|
+
if (this.animationFrameId) {
|
780
|
+
cancelAnimationFrame(this.animationFrameId)
|
781
|
+
this.animationFrameId = null
|
782
|
+
}
|
740
783
|
setTimeout(() => {
|
741
784
|
this.isClickOutsideActive = false
|
742
785
|
}, 10)
|
@@ -749,11 +792,30 @@
|
|
749
792
|
})
|
750
793
|
}
|
751
794
|
},
|
795
|
+
isSelectDropdownShown(isShown) {
|
796
|
+
if (!isShown) return
|
797
|
+
// Need to wait for 1ms to make sure the dropdown menu is shown in the DOM
|
798
|
+
// before getting the distance between the select and the dropdown menu
|
799
|
+
setTimeout(() => {
|
800
|
+
this.getDistanceBetweenSelectAndDropdownMenu()
|
801
|
+
}, 100)
|
802
|
+
},
|
803
|
+
selectTopPosition() {
|
804
|
+
this.dropdownPosition.top =
|
805
|
+
this.selectTopPosition +
|
806
|
+
this.$refs.select.$el.clientHeight +
|
807
|
+
this.selectAndDropdownDistance
|
808
|
+
},
|
752
809
|
},
|
753
810
|
mounted() {
|
754
811
|
this.observeDropdownHeight()
|
755
812
|
this.observeSelectWidth()
|
756
813
|
window.addEventListener('resize', this.handleSetDropdownOffet)
|
814
|
+
if (!this.isFixedDropdownPosition)
|
815
|
+
document.body.addEventListener(
|
816
|
+
'scroll',
|
817
|
+
this.calculateSelectTopPosition
|
818
|
+
)
|
757
819
|
},
|
758
820
|
beforeMount() {
|
759
821
|
this.selectedValue = this.value
|
@@ -762,6 +824,12 @@
|
|
762
824
|
window.removeEventListener('resize', this.handleSetDropdownOffet)
|
763
825
|
if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
|
764
826
|
if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
|
827
|
+
if (!this.isFixedDropdownPosition) {
|
828
|
+
document.body.removeEventListener(
|
829
|
+
'scroll',
|
830
|
+
this.calculateSelectTopPosition
|
831
|
+
)
|
832
|
+
}
|
765
833
|
},
|
766
834
|
unmounted() {
|
767
835
|
document.removeEventListener('click', this.clickOutside)
|
@@ -837,7 +905,9 @@
|
|
837
905
|
this.$refs.select.$el == event.target ||
|
838
906
|
this.$refs.select.$el.contains(event.target) ||
|
839
907
|
event.target.id === 'more-button' ||
|
840
|
-
event.target.
|
908
|
+
event.target.closest('.options-container') ||
|
909
|
+
event.target.parentNode === dropdownRef.$el ||
|
910
|
+
dropdownRef.$el.contains(event.target)
|
841
911
|
) {
|
842
912
|
return
|
843
913
|
} else {
|
@@ -867,11 +937,11 @@
|
|
867
937
|
return
|
868
938
|
}
|
869
939
|
await this.$nextTick()
|
870
|
-
|
940
|
+
this.isDisplayedAtBottom = await this.generateDropdownPosition()
|
871
941
|
// If the dropdown menu is going to be displayed at the bottom,
|
872
942
|
// we need reverify its position after a dom update (nextTick)
|
873
943
|
await this.$nextTick()
|
874
|
-
if (isDisplayedAtBottom) this.generateDropdownPosition()
|
944
|
+
if (this.isDisplayedAtBottom) this.generateDropdownPosition()
|
875
945
|
},
|
876
946
|
async generateDropdownPosition() {
|
877
947
|
const isDropdownNotCompletelyVisible =
|
@@ -964,6 +1034,25 @@
|
|
964
1034
|
}
|
965
1035
|
}
|
966
1036
|
},
|
1037
|
+
getDistanceBetweenSelectAndDropdownMenu() {
|
1038
|
+
const wholeSelectTopPosition =
|
1039
|
+
this.selectTopPosition + this.$refs.select.$el.clientHeight
|
1040
|
+
this.selectAndDropdownDistance =
|
1041
|
+
this.dropdownPosition.top - wholeSelectTopPosition
|
1042
|
+
},
|
1043
|
+
calculateSelectTopPosition() {
|
1044
|
+
const selectRef = this.$refs.select
|
1045
|
+
if (selectRef) {
|
1046
|
+
const currentTopPosition =
|
1047
|
+
selectRef.$el.getBoundingClientRect().top + window.scrollY
|
1048
|
+
if (this.selectTopPosition !== currentTopPosition) {
|
1049
|
+
this.selectTopPosition = currentTopPosition
|
1050
|
+
}
|
1051
|
+
}
|
1052
|
+
this.animationFrameId = requestAnimationFrame(
|
1053
|
+
this.calculateSelectTopPosition
|
1054
|
+
)
|
1055
|
+
},
|
967
1056
|
},
|
968
1057
|
}
|
969
1058
|
</script>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
/* eslint-disable */
|
2
|
+
import { mount } from '@vue/test-utils'
|
3
|
+
import ActionModal from '@/components/modals/actionModal'
|
4
|
+
import theme from '@/assets/theme'
|
5
|
+
|
6
|
+
describe('ActionModal Component', () => {
|
7
|
+
let wrapper
|
8
|
+
|
9
|
+
beforeEach(() => {
|
10
|
+
wrapper = mount(ActionModal, {
|
11
|
+
props: {
|
12
|
+
isOpen: true,
|
13
|
+
buttonText: 'Close',
|
14
|
+
},
|
15
|
+
slots: {
|
16
|
+
title: 'Sample title',
|
17
|
+
body: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed tincidunt commodo mollis. Fusce urna felis, malesuada sed elementum et, fermentum ac massa. Integer in massa vel orci fermentum bibendum in ut ante. Donec risus risus, luctus quis ex a, pulvinar placerat lacus. Sed pharetra augue a elit volutpat, eu dignissim ex pretium. Aenean imperdiet, nulla in pharetra rutrum, mauris mauris tincidunt tellus, non tempus quam lorem laoreet lectus.',
|
18
|
+
buttons: '<button @click="closeAction">Close</button>',
|
19
|
+
},
|
20
|
+
global: {
|
21
|
+
provide: {
|
22
|
+
theme,
|
23
|
+
},
|
24
|
+
},
|
25
|
+
})
|
26
|
+
})
|
27
|
+
|
28
|
+
test('renders ActionModal component with default props', () => {
|
29
|
+
expect(wrapper.find('[data-test-id="actionModal"]').exists()).toBe(true)
|
30
|
+
|
31
|
+
expect(wrapper.vm.isOpen).toBe(true)
|
32
|
+
})
|
33
|
+
|
34
|
+
test('action modal slots is display when user passed slots content', () => {
|
35
|
+
const modalTitleEl = wrapper.find('[data-test-id="modal_title"]')
|
36
|
+
expect(modalTitleEl.text()).toBe('Sample title')
|
37
|
+
|
38
|
+
const modalBodyEl = wrapper.find('[data-test-id="modal_body"]')
|
39
|
+
expect(modalBodyEl.text()).toContain('Lorem ipsum dolor sit amet')
|
40
|
+
|
41
|
+
const modalActionButton = wrapper.find('[data-test-id="modal_buttons"]')
|
42
|
+
expect(modalActionButton.text()).toContain('Close')
|
43
|
+
})
|
44
|
+
|
45
|
+
test('action modal on-close event is emitted when modal close button is clicked', async () => {
|
46
|
+
const modalCloseButton = wrapper.find('.close')
|
47
|
+
|
48
|
+
modalCloseButton.trigger('click')
|
49
|
+
await wrapper.vm.$nextTick()
|
50
|
+
expect(wrapper.emitted('on-close')).toBeTruthy()
|
51
|
+
})
|
52
|
+
})
|