@eturnity/eturnity_reusable_components 7.24.2 → 7.24.3
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/consumption_tariffs.svg +43 -0
- package/src/assets/svgIcons/electricity_tariff.svg +3 -0
- package/src/assets/svgIcons/handle.svg +5 -0
- package/src/assets/svgIcons/summer.svg +3 -0
- package/src/components/buttons/mainButton/index.vue +23 -1
- package/src/components/collapsableInfoText/index.vue +125 -0
- package/src/components/filter/filterSettings.vue +2 -0
- package/src/components/inputs/inputText/index.vue +20 -4
- package/src/components/inputs/radioButton/index.vue +5 -2
- package/src/components/inputs/select/index.vue +34 -11
- package/src/components/rangeSlider/Slider.vue +547 -0
- package/src/components/rangeSlider/index.vue +517 -0
- package/src/components/rangeSlider/utils/dom.js +49 -0
- package/src/components/rangeSlider/utils/fns.js +26 -0
- package/src/components/threeDots/index.vue +22 -8
- package/src/helpers/currencyMapping.js +28 -0
- package/src/mixins/inputValidations.js +97 -0
@@ -0,0 +1,517 @@
|
|
1
|
+
<template>
|
2
|
+
<RangeSliderContainer>
|
3
|
+
<Labels v-if="topLabels && topLabels.length > 0">
|
4
|
+
<Label v-for="label in topLabels" :key="label">
|
5
|
+
{{ label }}
|
6
|
+
</Label>
|
7
|
+
</Labels>
|
8
|
+
|
9
|
+
<BarContainer v-if="leftLabels && leftLabels.length > 0">
|
10
|
+
<BarWrapper v-for="(label, index) in leftLabels" :key="index">
|
11
|
+
<VerticalLabel>{{ label.name }}</VerticalLabel>
|
12
|
+
<BarSlider>
|
13
|
+
<Bar
|
14
|
+
@click.native.stop="
|
15
|
+
onBarRightClick({ event: $event, label, type: 'add' })
|
16
|
+
"
|
17
|
+
:data-id="`slider_bar_${dataLocation}_${label.id}`"
|
18
|
+
>
|
19
|
+
<SliderWrapper>
|
20
|
+
<Slider
|
21
|
+
v-for="(bar, index) in label.selectedTariffs"
|
22
|
+
:dataId="`slider_bar_item_${dataLocation}_${label.id}_${bar.name}`"
|
23
|
+
:key="bar.id"
|
24
|
+
:draggable="!disabled"
|
25
|
+
:resizable="!disabled"
|
26
|
+
:color="
|
27
|
+
hasOverlap && OverlapId.includes(label.id)
|
28
|
+
? '#ff5656'
|
29
|
+
: bar.color
|
30
|
+
"
|
31
|
+
:minWidth="minWidth"
|
32
|
+
:min="bar.min"
|
33
|
+
:max="bar.max"
|
34
|
+
:z="index"
|
35
|
+
:step="step"
|
36
|
+
:stepCount="stepCount"
|
37
|
+
:subStepCount="subStepCount"
|
38
|
+
@dragStop="
|
39
|
+
onChange('drag', {
|
40
|
+
itemId: bar.id,
|
41
|
+
parentId: bar.parentId,
|
42
|
+
entityId: label.id,
|
43
|
+
...$event
|
44
|
+
})
|
45
|
+
"
|
46
|
+
@resizeStop="
|
47
|
+
onChange('resize', {
|
48
|
+
itemId: bar.id,
|
49
|
+
entityId: label.id,
|
50
|
+
...$event
|
51
|
+
})
|
52
|
+
"
|
53
|
+
@click.native.stop="
|
54
|
+
onBarTariffClick({ item: bar, type: 'delete', label })
|
55
|
+
"
|
56
|
+
@activated="onActivateBar({ item: bar })"
|
57
|
+
@deactivated="onDeactivateBar()"
|
58
|
+
>
|
59
|
+
<template #mr>
|
60
|
+
<HandleIcon />
|
61
|
+
</template>
|
62
|
+
<template #ml>
|
63
|
+
<HandleIcon />
|
64
|
+
</template>
|
65
|
+
</Slider>
|
66
|
+
</SliderWrapper>
|
67
|
+
</Bar>
|
68
|
+
<Ruler>
|
69
|
+
<RulerRule v-for="n in stepCount" :key="n"></RulerRule>
|
70
|
+
</Ruler>
|
71
|
+
<SubRuler>
|
72
|
+
<RulerSubRule v-for="n in subStepCount" :key="n"></RulerSubRule>
|
73
|
+
</SubRuler>
|
74
|
+
<ErrorMessage
|
75
|
+
v-if="!canOverlap && hasOverlap && OverlapId.includes(label.id)"
|
76
|
+
>
|
77
|
+
*{{ $gettext('overlap_error_message') }}
|
78
|
+
</ErrorMessage>
|
79
|
+
</BarSlider>
|
80
|
+
</BarWrapper>
|
81
|
+
</BarContainer>
|
82
|
+
<bar-options-container
|
83
|
+
v-if="showBarOptions"
|
84
|
+
:top="barOptionsPosition.y"
|
85
|
+
:left="barOptionsPosition.x"
|
86
|
+
ref="barDropdown"
|
87
|
+
>
|
88
|
+
<bar-item-container
|
89
|
+
v-for="item in barOptionsList"
|
90
|
+
:key="item.id"
|
91
|
+
@click="
|
92
|
+
onBarTariffClick({ item, type: barOptionsType, label: activeLabel })
|
93
|
+
"
|
94
|
+
>
|
95
|
+
<AddIcon />
|
96
|
+
<bar-item-text>{{ item.name }}</bar-item-text>
|
97
|
+
</bar-item-container>
|
98
|
+
</bar-options-container>
|
99
|
+
</RangeSliderContainer>
|
100
|
+
</template>
|
101
|
+
|
102
|
+
<script>
|
103
|
+
import styled from 'vue3-styled-components'
|
104
|
+
import handleSVG from '../../assets/svgIcons/handle.svg'
|
105
|
+
import add from '../../assets/svgIcons/add_icon.svg'
|
106
|
+
|
107
|
+
import SliderComponent from './Slider'
|
108
|
+
|
109
|
+
const wrapperAttrs = { width: String, height: String }
|
110
|
+
const SliderWrapper = styled('div', wrapperAttrs)`
|
111
|
+
position: relative;
|
112
|
+
display: flex;
|
113
|
+
height: ${(props) => props.height || '24px'};
|
114
|
+
width: ${(props) => props.width || '100%'};
|
115
|
+
`
|
116
|
+
|
117
|
+
const sliderAttrs = { color: String, draggable: Boolean }
|
118
|
+
const Slider = styled(SliderComponent, sliderAttrs)`
|
119
|
+
cursor: ${(props) => (props.draggable ? 'pointer' : 'not-allowed')};
|
120
|
+
opacity: 0.7;
|
121
|
+
display: flex;
|
122
|
+
justify-content: space-between;
|
123
|
+
align-items: center;
|
124
|
+
border: unset !important;
|
125
|
+
background-color: ${(props) => props.color};
|
126
|
+
`
|
127
|
+
|
128
|
+
const ErrorMessage = styled.p`
|
129
|
+
color: ${(props) => props.theme.colors.red};
|
130
|
+
font-style: italic;
|
131
|
+
font-size: 13px;
|
132
|
+
margin-top: 5px;
|
133
|
+
`
|
134
|
+
|
135
|
+
const Bar = styled.div`
|
136
|
+
display: flex;
|
137
|
+
margin-bottom: -30px;
|
138
|
+
margin-left: 1px;
|
139
|
+
background-color: #f6faff;
|
140
|
+
width: 100%;
|
141
|
+
background-color: ${(props) => props.theme.colors.gray1};
|
142
|
+
`
|
143
|
+
|
144
|
+
const Ruler = styled.div`
|
145
|
+
margin: 10px 0px -5px 0px;
|
146
|
+
display: flex;
|
147
|
+
overflow: hidden;
|
148
|
+
`
|
149
|
+
|
150
|
+
const RulerRule = styled.div`
|
151
|
+
border-left: solid 1px ${(props) => props.theme.colors.grey2};
|
152
|
+
border-bottom: solid 1px ${(props) => props.theme.colors.grey2};
|
153
|
+
display: flex;
|
154
|
+
flex-grow: 1;
|
155
|
+
flex-shrink: 1;
|
156
|
+
padding: 10px 0px;
|
157
|
+
|
158
|
+
&:last-child {
|
159
|
+
border-right: solid 1px ${(props) => props.theme.colors.grey2};
|
160
|
+
}
|
161
|
+
`
|
162
|
+
|
163
|
+
const SubRuler = styled.div`
|
164
|
+
margin: -7px 0px -5px 0px;
|
165
|
+
display: flex;
|
166
|
+
`
|
167
|
+
|
168
|
+
const RulerSubRule = styled.div`
|
169
|
+
border-left: solid 1px ${(props) => props.theme.colors.grey2};
|
170
|
+
border-bottom: solid 1px ${(props) => props.theme.colors.grey2};
|
171
|
+
display: flex;
|
172
|
+
flex-grow: 1;
|
173
|
+
flex-shrink: 1;
|
174
|
+
padding: 3px 0px;
|
175
|
+
|
176
|
+
&:last-child {
|
177
|
+
border-right: solid 1px ${(props) => props.theme.colors.grey2};
|
178
|
+
}
|
179
|
+
|
180
|
+
&:nth-child(odd) {
|
181
|
+
margin-top: -5px;
|
182
|
+
padding: 5px 0px;
|
183
|
+
}
|
184
|
+
`
|
185
|
+
|
186
|
+
const BarSlider = styled.div`
|
187
|
+
width: 100%;
|
188
|
+
`
|
189
|
+
|
190
|
+
const BarContainer = styled.div`
|
191
|
+
display: flex;
|
192
|
+
flex-direction: column;
|
193
|
+
`
|
194
|
+
|
195
|
+
const BarWrapper = styled.div`
|
196
|
+
display: flex;
|
197
|
+
flex-direction: row;
|
198
|
+
margin: 20px 0px;
|
199
|
+
align-items: center;
|
200
|
+
`
|
201
|
+
|
202
|
+
const RangeSliderContainer = styled.div`
|
203
|
+
display: flex;
|
204
|
+
position: relative;
|
205
|
+
padding: 20px 10px;
|
206
|
+
flex-direction: column;
|
207
|
+
user-select: none;
|
208
|
+
width: 100%;
|
209
|
+
`
|
210
|
+
|
211
|
+
const Labels = styled.div`
|
212
|
+
display: flex;
|
213
|
+
justify-content: space-between;
|
214
|
+
padding: 0px;
|
215
|
+
margin: 10px -100px 0px 100px;
|
216
|
+
width: calc(100% - 100px);
|
217
|
+
`
|
218
|
+
|
219
|
+
const Label = styled.div`
|
220
|
+
font-size: 80%;
|
221
|
+
display: flex;
|
222
|
+
width: 1px;
|
223
|
+
justify-content: center;
|
224
|
+
`
|
225
|
+
|
226
|
+
const VerticalLabel = styled.div`
|
227
|
+
text-align: left;
|
228
|
+
min-width: 100px;
|
229
|
+
font-size: 13px;
|
230
|
+
`
|
231
|
+
|
232
|
+
const AddIcon = styled(add)`
|
233
|
+
width: 33px;
|
234
|
+
height: 29px;
|
235
|
+
fill: black
|
236
|
+
margin-left: -17px;
|
237
|
+
margin-top: -10px;
|
238
|
+
`
|
239
|
+
|
240
|
+
const HandleIcon = styled(handleSVG)`
|
241
|
+
width: 13px;
|
242
|
+
min-width: 0;
|
243
|
+
margin: -6px;
|
244
|
+
`
|
245
|
+
|
246
|
+
const BarOptionAttrs = { top: Number, left: Number }
|
247
|
+
const BarOptionsContainer = styled('div', BarOptionAttrs)`
|
248
|
+
display: grid;
|
249
|
+
position: fixed;
|
250
|
+
z-index: 9999;
|
251
|
+
border-radius: 4px;
|
252
|
+
background-color: ${(props) => props.theme.colors.white};
|
253
|
+
padding: 6px 10px;
|
254
|
+
border: 1px solid ${(props) => props.theme.colors.grey4};
|
255
|
+
top: ${(props) => props.top + 'px'};
|
256
|
+
left: ${(props) => props.left + 'px'};
|
257
|
+
`
|
258
|
+
|
259
|
+
const BarItemContainer = styled.div`
|
260
|
+
display: grid;
|
261
|
+
grid-template-columns: auto 1fr;
|
262
|
+
grid-gap: 12px;
|
263
|
+
align-items: center;
|
264
|
+
cursor: pointer;
|
265
|
+
padding: 6px 10px;
|
266
|
+
border-radius: 4px;
|
267
|
+
|
268
|
+
&:hover {
|
269
|
+
background-color: ${(props) => props.theme.colors.lightGray};
|
270
|
+
}
|
271
|
+
`
|
272
|
+
|
273
|
+
const BarItemText = styled.div`
|
274
|
+
font-size: 13px;
|
275
|
+
`
|
276
|
+
|
277
|
+
export default {
|
278
|
+
name: 'RangeSlider',
|
279
|
+
props: {
|
280
|
+
dataLocation: { type: String, default: '' },
|
281
|
+
tariffItems: { type: Array, default: () => [] },
|
282
|
+
labels: { type: Array, default: () => [] },
|
283
|
+
rangeMargin: { type: Number, default: 1 },
|
284
|
+
step: { type: Number, default: 1 },
|
285
|
+
minWidth: { type: Number, default: 1 },
|
286
|
+
canOverlap: { type: Boolean, default: true },
|
287
|
+
disabled: { type: Boolean, default: false }
|
288
|
+
},
|
289
|
+
components: {
|
290
|
+
Bar,
|
291
|
+
Label,
|
292
|
+
Labels,
|
293
|
+
Ruler,
|
294
|
+
Slider,
|
295
|
+
AddIcon,
|
296
|
+
SubRuler,
|
297
|
+
BarSlider,
|
298
|
+
RulerRule,
|
299
|
+
HandleIcon,
|
300
|
+
BarWrapper,
|
301
|
+
ErrorMessage,
|
302
|
+
RulerSubRule,
|
303
|
+
BarContainer,
|
304
|
+
SliderWrapper,
|
305
|
+
VerticalLabel,
|
306
|
+
RangeSliderContainer,
|
307
|
+
BarOptionsContainer,
|
308
|
+
BarItemContainer,
|
309
|
+
BarItemText
|
310
|
+
},
|
311
|
+
data() {
|
312
|
+
return {
|
313
|
+
showBarOptions: false,
|
314
|
+
barOptionsPosition: { x: 0, y: 0 },
|
315
|
+
barOptionsList: [],
|
316
|
+
barOptionsType: null, // can be "add" or "delete"
|
317
|
+
activeLabel: null,
|
318
|
+
activeItem: null,
|
319
|
+
OverlapId: [],
|
320
|
+
hasOverlap: false
|
321
|
+
}
|
322
|
+
},
|
323
|
+
computed: {
|
324
|
+
maximum() {
|
325
|
+
if (!this.labels.length) return
|
326
|
+
|
327
|
+
return this.topLabels.at(-1)
|
328
|
+
},
|
329
|
+
minimum() {
|
330
|
+
if (!this.labels.length) return
|
331
|
+
|
332
|
+
return this.topLabels[0]
|
333
|
+
},
|
334
|
+
topLabels() {
|
335
|
+
if (!this.labels.length) return
|
336
|
+
const labels = this.labels.find((label) => label.placement === 'top')
|
337
|
+
|
338
|
+
return labels ? labels.value : []
|
339
|
+
},
|
340
|
+
leftLabels() {
|
341
|
+
if (!this.labels.length) return
|
342
|
+
const labels = this.labels.find((label) => label.placement === 'left')
|
343
|
+
return labels ? labels.value : []
|
344
|
+
},
|
345
|
+
stepCount() {
|
346
|
+
let labels = this.topLabels || []
|
347
|
+
|
348
|
+
if (labels.length) {
|
349
|
+
return labels.length - 1
|
350
|
+
}
|
351
|
+
|
352
|
+
return Math.floor((this.maximum - this.minimum) / this.step)
|
353
|
+
},
|
354
|
+
subStepCount() {
|
355
|
+
let labels = this.topLabels || []
|
356
|
+
|
357
|
+
if (labels.length && this.step) {
|
358
|
+
return (this.maximum - this.minimum) / this.step
|
359
|
+
}
|
360
|
+
|
361
|
+
return 0
|
362
|
+
}
|
363
|
+
},
|
364
|
+
methods: {
|
365
|
+
onChange(type, value) {
|
366
|
+
this.$emit(type, value)
|
367
|
+
},
|
368
|
+
checkOverlap(value, tariffs) {
|
369
|
+
// Check if the tariffs overlap
|
370
|
+
const min = parseFloat(value.min)
|
371
|
+
const max = parseFloat(value.max)
|
372
|
+
|
373
|
+
return tariffs.some((tariff) => {
|
374
|
+
if (tariff.id === value.itemId || tariff.id === value.id) return false
|
375
|
+
|
376
|
+
return (
|
377
|
+
min === tariff.min ||
|
378
|
+
max === tariff.max ||
|
379
|
+
(min > tariff.min && min < tariff.max) ||
|
380
|
+
(max > tariff.min && max < tariff.max) ||
|
381
|
+
(min < tariff.min && max > tariff.max)
|
382
|
+
)
|
383
|
+
})
|
384
|
+
},
|
385
|
+
barOptionLabel(value) {
|
386
|
+
if (this.barOptionsType === 'add')
|
387
|
+
return `${this.$gettext('Add')} ${value}`
|
388
|
+
|
389
|
+
return `${this.$gettext('Remove')} ${value}`
|
390
|
+
},
|
391
|
+
onActivateBar({ item }) {
|
392
|
+
this.$emit('activate')
|
393
|
+
this.activeItem = item
|
394
|
+
document.addEventListener('keydown', this.onKeyDownDelete)
|
395
|
+
},
|
396
|
+
onDeactivateBar() {
|
397
|
+
this.$emit('deactivate')
|
398
|
+
this.activeItem = null
|
399
|
+
document.removeEventListener('keydown', this.onKeyDownDelete)
|
400
|
+
},
|
401
|
+
onKeyDownDelete(event) {
|
402
|
+
// Check if the pressed key is the Delete or Backspace key
|
403
|
+
if (
|
404
|
+
(event.key === 'Delete' || event.key === 'Backspace') &&
|
405
|
+
this.activeItem
|
406
|
+
) {
|
407
|
+
this.$emit('on-bar-tariff-click', {
|
408
|
+
type: 'delete',
|
409
|
+
item: this.activeItem,
|
410
|
+
label: this.activeLabel
|
411
|
+
})
|
412
|
+
this.activeItem = null
|
413
|
+
}
|
414
|
+
},
|
415
|
+
onBarTariffClick({ item, type, label }) {
|
416
|
+
if (this.disabled) return
|
417
|
+
|
418
|
+
this.$emit('on-bar-tariff-click', {
|
419
|
+
type,
|
420
|
+
item,
|
421
|
+
label
|
422
|
+
})
|
423
|
+
|
424
|
+
this.activeLabel = label
|
425
|
+
this.barOptionsType = type
|
426
|
+
this.showBarOptions = false
|
427
|
+
},
|
428
|
+
setBarOptions(bar) {
|
429
|
+
this.barOptionsList = []
|
430
|
+
|
431
|
+
if (this.barOptionsType === 'add') {
|
432
|
+
this.tariffItems.forEach((item) => {
|
433
|
+
if (item.name && item.name.length) {
|
434
|
+
this.barOptionsList.push(item)
|
435
|
+
}
|
436
|
+
})
|
437
|
+
} else {
|
438
|
+
// add based on the index in the chart.
|
439
|
+
this.barOptionsList.push({
|
440
|
+
name: bar.name,
|
441
|
+
id: bar.id
|
442
|
+
})
|
443
|
+
}
|
444
|
+
},
|
445
|
+
onBarRightClick({ event, label, type, bar }) {
|
446
|
+
if (this.disabled) return
|
447
|
+
|
448
|
+
// type can be "add", "delete"
|
449
|
+
// if "add", show all tariffItems for the group
|
450
|
+
// if "delete", only show the delete with the tariff name
|
451
|
+
event.preventDefault()
|
452
|
+
this.activeLabel = label
|
453
|
+
this.barOptionsType = type
|
454
|
+
this.setBarOptions(bar)
|
455
|
+
|
456
|
+
if (this.barOptionsList.length) {
|
457
|
+
this.showBarOptions = true
|
458
|
+
this.barOptionsPosition = { x: event.clientX, y: event.clientY }
|
459
|
+
document.addEventListener('click', this.handleOutsideClick)
|
460
|
+
} else {
|
461
|
+
this.showBarOptions = false
|
462
|
+
}
|
463
|
+
},
|
464
|
+
handleOutsideClick(event) {
|
465
|
+
// Check if the click occurred outside the dropdown
|
466
|
+
if (
|
467
|
+
this.$refs.barDropdown &&
|
468
|
+
!this.$refs.barDropdown.$el.contains(event.target)
|
469
|
+
) {
|
470
|
+
// Hide the dropdown
|
471
|
+
this.showBarOptions = false
|
472
|
+
// Remove the global click event listener
|
473
|
+
document.removeEventListener('click', this.handleOutsideClick)
|
474
|
+
}
|
475
|
+
}
|
476
|
+
},
|
477
|
+
beforeDestroy() {
|
478
|
+
// Remove the global click event listener to prevent memory leaks
|
479
|
+
document.removeEventListener('click', this.handleOutsideClick)
|
480
|
+
document.removeEventListener('keydown', this.onKeyDownDelete)
|
481
|
+
},
|
482
|
+
watch: {
|
483
|
+
labels(newVal, oldVal) {
|
484
|
+
const overlapContainer = []
|
485
|
+
|
486
|
+
//check items for overlap
|
487
|
+
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
488
|
+
const labels = newVal.find((label) => label.placement === 'left')
|
489
|
+
|
490
|
+
if (labels) {
|
491
|
+
labels.value.forEach((label) => {
|
492
|
+
label.selectedTariffs.forEach((tariff) => {
|
493
|
+
const hasOverlap = this.checkOverlap(
|
494
|
+
tariff,
|
495
|
+
label.selectedTariffs
|
496
|
+
)
|
497
|
+
|
498
|
+
if (hasOverlap) overlapContainer.push(label.id)
|
499
|
+
})
|
500
|
+
})
|
501
|
+
}
|
502
|
+
|
503
|
+
const hasOverlap = overlapContainer.length > 0
|
504
|
+
|
505
|
+
if (!hasOverlap) {
|
506
|
+
this.OverlapId = []
|
507
|
+
} else {
|
508
|
+
this.OverlapId = [...new Set(overlapContainer)]
|
509
|
+
}
|
510
|
+
|
511
|
+
this.hasOverlap = hasOverlap
|
512
|
+
this.$emit('has-overlap', hasOverlap)
|
513
|
+
}
|
514
|
+
}
|
515
|
+
}
|
516
|
+
}
|
517
|
+
</script>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { isFunction } from './fns'
|
2
|
+
|
3
|
+
export function matchesSelectorToParentElements (el, selector, baseNode) {
|
4
|
+
let node = el
|
5
|
+
|
6
|
+
const matchesSelectorFunc = [
|
7
|
+
'matches',
|
8
|
+
'webkitMatchesSelector',
|
9
|
+
'mozMatchesSelector',
|
10
|
+
'msMatchesSelector',
|
11
|
+
'oMatchesSelector'
|
12
|
+
].find(func => isFunction(node[func]))
|
13
|
+
|
14
|
+
if (!isFunction(node[matchesSelectorFunc])) return false
|
15
|
+
|
16
|
+
do {
|
17
|
+
if (node[matchesSelectorFunc](selector)) return true
|
18
|
+
if (node === baseNode) return false
|
19
|
+
node = node.parentNode
|
20
|
+
} while (node)
|
21
|
+
|
22
|
+
return false
|
23
|
+
}
|
24
|
+
|
25
|
+
export function addEvent (el, event, handler) {
|
26
|
+
if (!el) {
|
27
|
+
return
|
28
|
+
}
|
29
|
+
if (el.attachEvent) {
|
30
|
+
el.attachEvent('on' + event, handler)
|
31
|
+
} else if (el.addEventListener) {
|
32
|
+
el.addEventListener(event, handler, true)
|
33
|
+
} else {
|
34
|
+
el['on' + event] = handler
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
export function removeEvent (el, event, handler) {
|
39
|
+
if (!el) {
|
40
|
+
return
|
41
|
+
}
|
42
|
+
if (el.detachEvent) {
|
43
|
+
el.detachEvent('on' + event, handler)
|
44
|
+
} else if (el.removeEventListener) {
|
45
|
+
el.removeEventListener(event, handler, true)
|
46
|
+
} else {
|
47
|
+
el['on' + event] = null
|
48
|
+
}
|
49
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
export function isFunction(func) {
|
2
|
+
return (
|
3
|
+
typeof func === 'function' ||
|
4
|
+
Object.prototype.toString.call(func) === '[object Function]'
|
5
|
+
)
|
6
|
+
}
|
7
|
+
|
8
|
+
export function snapToGrid(grid, pendingX) {
|
9
|
+
return Math.round(pendingX / grid) * grid
|
10
|
+
}
|
11
|
+
|
12
|
+
export function computeWidth(left, right) {
|
13
|
+
return right - left
|
14
|
+
}
|
15
|
+
|
16
|
+
export function restrictToBounds(value, min, max) {
|
17
|
+
if (min !== null && value < min) {
|
18
|
+
return min
|
19
|
+
}
|
20
|
+
|
21
|
+
if (max !== null && max < value) {
|
22
|
+
return max
|
23
|
+
}
|
24
|
+
|
25
|
+
return value
|
26
|
+
}
|
@@ -1,5 +1,9 @@
|
|
1
1
|
<template>
|
2
|
-
<page-container
|
2
|
+
<page-container
|
3
|
+
@click="toggleButton()"
|
4
|
+
ref="pageContainer"
|
5
|
+
:activated="isOpen"
|
6
|
+
>
|
3
7
|
<button-container ref="dropdownItem">
|
4
8
|
<dot-item />
|
5
9
|
<dot-item />
|
@@ -44,7 +48,9 @@
|
|
44
48
|
:key="item.value"
|
45
49
|
:data-id="item.dataId"
|
46
50
|
tabindex="0"
|
47
|
-
@click.stop="
|
51
|
+
@click.stop="
|
52
|
+
onSelect({ item: item, hasChildren: hasChildren(item) })
|
53
|
+
"
|
48
54
|
@keyup.enter="
|
49
55
|
onSelect({ item: item, hasChildren: hasChildren(item) })
|
50
56
|
"
|
@@ -136,7 +142,8 @@ const PageContainer = styled('div', PageContainerAttrs)`
|
|
136
142
|
width: 30px;
|
137
143
|
height: 30px;
|
138
144
|
border-radius: 4px;
|
139
|
-
background-color: ${(props) =>
|
145
|
+
background-color: ${(props) =>
|
146
|
+
props.activated ? props.theme.colors.grey5 : ''};
|
140
147
|
|
141
148
|
&:hover {
|
142
149
|
background-color: ${(props) => props.theme.colors.grey5};
|
@@ -325,21 +332,28 @@ export default {
|
|
325
332
|
const positionArray = this.determineElementQuarter(button, rectButton)
|
326
333
|
contextMenu.style.transform = ''
|
327
334
|
if (positionArray.includes('left')) {
|
328
|
-
contextMenu.style.left =
|
335
|
+
contextMenu.style.left =
|
336
|
+
rectButton.right - rectRelativeParent.left + 5 + 'px'
|
329
337
|
} else {
|
330
|
-
contextMenu.style.left =
|
338
|
+
contextMenu.style.left =
|
339
|
+
rectButton.left - rectRelativeParent.left - 5 + 'px'
|
331
340
|
contextMenu.style.transform = 'translateX(-100%)'
|
332
341
|
}
|
333
342
|
if (positionArray.includes('top')) {
|
334
|
-
contextMenu.style.top =
|
343
|
+
contextMenu.style.top = rectButton.top - rectRelativeParent.top + 'px'
|
335
344
|
} else {
|
336
|
-
contextMenu.style.top =
|
345
|
+
contextMenu.style.top =
|
346
|
+
rectButton.bottom - rectRelativeParent.top + 'px'
|
337
347
|
contextMenu.style.transform += ' translateY(-100%)'
|
338
348
|
}
|
339
349
|
},
|
340
350
|
findRelativeParent(element) {
|
341
351
|
while (element.parentElement) {
|
342
|
-
if (
|
352
|
+
if (
|
353
|
+
window.getComputedStyle(element.parentElement).position ===
|
354
|
+
'relative' ||
|
355
|
+
window.getComputedStyle(element.parentElement).position === 'absolute'
|
356
|
+
) {
|
343
357
|
return element.parentElement
|
344
358
|
}
|
345
359
|
element = element.parentElement
|
@@ -0,0 +1,28 @@
|
|
1
|
+
export const currencyMapping = (data) => {
|
2
|
+
let currency
|
3
|
+
|
4
|
+
switch (data) {
|
5
|
+
case 'EUR':
|
6
|
+
currency = 'ct'
|
7
|
+
break
|
8
|
+
case 'CHF':
|
9
|
+
currency = 'Rp.'
|
10
|
+
break
|
11
|
+
case 'SEK':
|
12
|
+
currency = 'öre'
|
13
|
+
break
|
14
|
+
case 'GBP':
|
15
|
+
currency = 'p'
|
16
|
+
break
|
17
|
+
case 'USD':
|
18
|
+
currency = 'ct'
|
19
|
+
break
|
20
|
+
case 'DKK':
|
21
|
+
currency = 'øre'
|
22
|
+
break
|
23
|
+
default:
|
24
|
+
currency = 'ct'
|
25
|
+
}
|
26
|
+
|
27
|
+
return currency
|
28
|
+
}
|