@eturnity/eturnity_reusable_components 7.45.5-qa-16-11.13.1 → 7.48.0
Sign up to get free protection for your applications and to get access to all the features.
- package/package.json +1 -1
- package/src/components/inputs/inputNumber/index.vue +77 -63
- package/src/components/inputs/searchInput/SearchInput.stories.js +51 -24
- package/src/components/inputs/searchInput/defaultProps.js +12 -0
- package/src/components/inputs/searchInput/index.vue +15 -7
- package/src/components/inputs/searchInput/searchInput.spec.js +65 -0
- package/src/components/inputs/select/index.vue +5 -57
- package/src/components/modals/modal/index.vue +27 -27
- package/src/helpers/numberConverter.js +1 -1
package/package.json
CHANGED
@@ -47,7 +47,7 @@
|
|
47
47
|
:show-linear-unit-name="showLinearUnitName"
|
48
48
|
:slot-size="slotSize"
|
49
49
|
:text-align="textAlign"
|
50
|
-
:value="
|
50
|
+
:value="formatWithCurrency(value)"
|
51
51
|
@blur="onInputBlur($event)"
|
52
52
|
@focus="focusInput()"
|
53
53
|
@input="onInput($event)"
|
@@ -59,7 +59,7 @@
|
|
59
59
|
|
60
60
|
<UnitContainer
|
61
61
|
v-if="unitName && showLinearUnitName && !hasSlot"
|
62
|
-
:has-length="
|
62
|
+
:has-length="!!textInput.length"
|
63
63
|
:is-error="isError"
|
64
64
|
>{{ unitName }}</UnitContainer
|
65
65
|
>
|
@@ -76,7 +76,7 @@
|
|
76
76
|
:disabled="isSelectDisabled"
|
77
77
|
:select-width="`${selectWidth}px`"
|
78
78
|
:show-border="false"
|
79
|
-
@input-change="
|
79
|
+
@input-change="$emit('select-change', $event)"
|
80
80
|
>
|
81
81
|
<template #selector>
|
82
82
|
<SelectText>{{ getSelectValue }}</SelectText>
|
@@ -339,18 +339,8 @@
|
|
339
339
|
background-color: ${({ theme }) => theme.colors.grey4};
|
340
340
|
`
|
341
341
|
|
342
|
-
const EVENT_TYPES = {
|
343
|
-
INPUT_FOCUS: 'input-focus',
|
344
|
-
INPUT_CHANGE: 'input-change',
|
345
|
-
INPUT_BLUR: 'input-blur',
|
346
|
-
PRESS_ENTER: 'on-enter-click',
|
347
|
-
INPUT_DRAG: 'on-input-drag',
|
348
|
-
SELECT_CHANGE: 'select-change',
|
349
|
-
}
|
350
|
-
|
351
342
|
export default {
|
352
343
|
name: 'InputNumber',
|
353
|
-
emits: [...Object.values(EVENT_TYPES)],
|
354
344
|
components: {
|
355
345
|
Container,
|
356
346
|
InputContainer,
|
@@ -529,10 +519,9 @@
|
|
529
519
|
},
|
530
520
|
data() {
|
531
521
|
return {
|
522
|
+
textInput: '',
|
532
523
|
isFocused: false,
|
533
524
|
warningIcon: warningIcon,
|
534
|
-
inputValue: null,
|
535
|
-
enteredValue: null,
|
536
525
|
}
|
537
526
|
},
|
538
527
|
computed: {
|
@@ -555,14 +544,6 @@
|
|
555
544
|
|
556
545
|
return item ? item.label : '-'
|
557
546
|
},
|
558
|
-
formattedValue() {
|
559
|
-
return this.formatWithCurrency(
|
560
|
-
this.isFocused ? this.enteredValue : this.inputValue
|
561
|
-
)
|
562
|
-
},
|
563
|
-
hasLength() {
|
564
|
-
return this.formattedValue !== null && this.formattedValue.length > 0
|
565
|
-
},
|
566
547
|
},
|
567
548
|
watch: {
|
568
549
|
focus(value) {
|
@@ -573,19 +554,30 @@
|
|
573
554
|
clearInput: function (value) {
|
574
555
|
if (value) {
|
575
556
|
// If the value is typed, then we should clear the textInput on Continue
|
576
|
-
this.
|
577
|
-
this.enteredValue = ''
|
557
|
+
this.textInput = ''
|
578
558
|
}
|
579
559
|
},
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
}
|
588
|
-
}
|
560
|
+
},
|
561
|
+
created() {
|
562
|
+
if (this.value) {
|
563
|
+
this.textInput = numberToString({
|
564
|
+
value: this.value,
|
565
|
+
numberPrecision: this.numberPrecision,
|
566
|
+
minDecimals: this.minDecimals,
|
567
|
+
})
|
568
|
+
} else if (this.defaultNumber !== null) {
|
569
|
+
this.textInput = numberToString({
|
570
|
+
value: this.defaultNumber,
|
571
|
+
numberPrecision: this.numberPrecision,
|
572
|
+
minDecimals: this.minDecimals,
|
573
|
+
})
|
574
|
+
} else if (this.minNumber !== null) {
|
575
|
+
this.textInput = numberToString({
|
576
|
+
value: this.minNumber,
|
577
|
+
numberPrecision: this.numberPrecision,
|
578
|
+
minDecimals: this.minDecimals,
|
579
|
+
})
|
580
|
+
}
|
589
581
|
},
|
590
582
|
mounted() {
|
591
583
|
if (this.focus) {
|
@@ -594,28 +586,29 @@
|
|
594
586
|
},
|
595
587
|
methods: {
|
596
588
|
onEnterPress() {
|
597
|
-
this.$emit(
|
589
|
+
this.$emit('on-enter-click')
|
598
590
|
this.$refs.inputField1.$el.blur()
|
599
591
|
},
|
600
|
-
onChangeHandler(
|
601
|
-
if (isNaN(
|
602
|
-
|
592
|
+
onChangeHandler(event) {
|
593
|
+
if (isNaN(event) || event === '') {
|
594
|
+
event = this.defaultNumber
|
603
595
|
? this.defaultNumber
|
604
596
|
: this.minNumber || this.minNumber === 0
|
605
597
|
? this.minNumber
|
606
|
-
:
|
598
|
+
: event
|
607
599
|
}
|
608
600
|
if (!this.allowNegative) {
|
609
|
-
|
601
|
+
event = Math.abs(event)
|
610
602
|
}
|
611
|
-
|
603
|
+
event = parseFloat(event)
|
612
604
|
// Need to return an integer rather than a string
|
613
|
-
|
605
|
+
this.$emit('input-change', event)
|
614
606
|
},
|
615
|
-
onEvaluateCode(
|
607
|
+
onEvaluateCode(event) {
|
616
608
|
// function to perform math on the code
|
617
609
|
// filter the string in case of any malicious content
|
618
|
-
|
610
|
+
const val = event.target.value
|
611
|
+
let filtered = val.replace('(auto)', '').replace(/[^-()\d/*+.,]/g, '')
|
619
612
|
filtered = filtered.split(/([-+*/()])/)
|
620
613
|
let formatted = filtered.map((item) => {
|
621
614
|
if (
|
@@ -673,28 +666,47 @@
|
|
673
666
|
return array
|
674
667
|
},
|
675
668
|
onInput(event) {
|
676
|
-
this.
|
677
|
-
if (!this.isFocused || this.enteredValue === this.inputValue) {
|
669
|
+
if (!this.isFocused) {
|
678
670
|
return
|
679
671
|
}
|
672
|
+
if (event.target.value === '') {
|
673
|
+
this.$emit('on-input', '')
|
674
|
+
}
|
680
675
|
let evaluatedVal
|
681
676
|
try {
|
682
|
-
evaluatedVal = this.onEvaluateCode(
|
677
|
+
evaluatedVal = this.onEvaluateCode(event)
|
683
678
|
} finally {
|
684
|
-
this.
|
685
|
-
|
686
|
-
if (this.isFocused && typeof this.enteredValue !== 'number') {
|
687
|
-
this.$emit(EVENT_TYPES.INPUT_CHANGE, this.inputValue)
|
679
|
+
if (evaluatedVal && this.value != evaluatedVal) {
|
680
|
+
this.$emit('on-input', evaluatedVal)
|
688
681
|
}
|
689
682
|
}
|
690
683
|
},
|
691
684
|
onInputBlur(e) {
|
692
685
|
this.isFocused = false
|
693
|
-
|
694
|
-
this
|
695
|
-
|
696
|
-
|
697
|
-
|
686
|
+
let value = e.target.value
|
687
|
+
let evaluatedInput = this.onEvaluateCode(e)
|
688
|
+
this.onChangeHandler(evaluatedInput ? evaluatedInput : value)
|
689
|
+
if ((evaluatedInput && value.length) || this.minNumber !== null) {
|
690
|
+
this.textInput = numberToString({
|
691
|
+
value:
|
692
|
+
evaluatedInput && value.length
|
693
|
+
? evaluatedInput
|
694
|
+
: this.defaultNumber
|
695
|
+
? this.defaultNumber
|
696
|
+
: this.minNumber,
|
697
|
+
numberPrecision: this.numberPrecision,
|
698
|
+
minDecimals: this.minDecimals,
|
699
|
+
})
|
700
|
+
}
|
701
|
+
let adjustedMinValue =
|
702
|
+
evaluatedInput && evaluatedInput.length
|
703
|
+
? evaluatedInput
|
704
|
+
: this.defaultNumber
|
705
|
+
? this.defaultNumber
|
706
|
+
: this.minNumber || this.minNumber === 0
|
707
|
+
? this.minNumber
|
708
|
+
: ''
|
709
|
+
this.$emit('input-blur', adjustedMinValue)
|
698
710
|
},
|
699
711
|
focusInput() {
|
700
712
|
if (this.disabled) {
|
@@ -704,7 +716,7 @@
|
|
704
716
|
this.$nextTick(() => {
|
705
717
|
this.$refs.inputField1.$el.select()
|
706
718
|
})
|
707
|
-
this.$emit(
|
719
|
+
this.$emit('input-focus')
|
708
720
|
},
|
709
721
|
blurInput() {
|
710
722
|
if (this.disabled) {
|
@@ -737,8 +749,6 @@
|
|
737
749
|
return input + ' ' + unit
|
738
750
|
} else if (!adjustedMinValue && adjustedMinValue !== 0) {
|
739
751
|
return ''
|
740
|
-
} else if (this.isFocused && this.numberPrecision > 0) {
|
741
|
-
return value
|
742
752
|
} else {
|
743
753
|
return this.numberToStringEnabled
|
744
754
|
? numberToString({
|
@@ -759,7 +769,14 @@
|
|
759
769
|
e.preventDefault()
|
760
770
|
let value = parseFloat(this.value || 0)
|
761
771
|
value += parseFloat(this.interactionStep) * parseInt(e.movementX)
|
762
|
-
this.$emit(
|
772
|
+
this.$emit('on-input-drag', value)
|
773
|
+
|
774
|
+
this.textInput = numberToString({
|
775
|
+
value: value && value.length ? value : this.minNumber,
|
776
|
+
numberPrecision: this.numberPrecision,
|
777
|
+
minDecimals: this.minDecimals,
|
778
|
+
})
|
779
|
+
//this.value=value
|
763
780
|
},
|
764
781
|
stopInteract(e) {
|
765
782
|
e.preventDefault()
|
@@ -767,9 +784,6 @@
|
|
767
784
|
window.removeEventListener('mouseup', this.stopInteract, false)
|
768
785
|
this.blurInput()
|
769
786
|
},
|
770
|
-
handleSelectChange(value) {
|
771
|
-
this.$emit(EVENT_TYPES.SELECT_CHANGE, value)
|
772
|
-
},
|
773
787
|
},
|
774
788
|
}
|
775
789
|
</script>
|
@@ -1,40 +1,67 @@
|
|
1
|
+
import { useArgs } from '@storybook/preview-api'
|
2
|
+
import { action } from '@storybook/addon-actions'
|
3
|
+
import defaultSearchInputProps from './defaultProps'
|
1
4
|
import SearchInput from './index.vue'
|
2
5
|
|
3
6
|
export default {
|
4
7
|
title: 'SearchInput',
|
5
8
|
component: SearchInput,
|
6
|
-
|
9
|
+
tags: ['autodocs'],
|
7
10
|
}
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
}
|
12
|
+
// To use:
|
13
|
+
|
14
|
+
const defaultProps = defaultSearchInputProps
|
15
|
+
|
16
|
+
const Template = (args) => {
|
17
|
+
const [currentArgs, updateArgs] = useArgs()
|
18
|
+
|
19
|
+
const handleInputChange = ($event) => {
|
20
|
+
action('on-change')($event)
|
21
|
+
updateArgs({ value: $event })
|
22
|
+
}
|
23
|
+
|
24
|
+
return {
|
25
|
+
components: { SearchInput },
|
26
|
+
setup() {
|
27
|
+
return { args: currentArgs, handleInputChange }
|
28
|
+
},
|
29
|
+
template: `
|
30
|
+
<SearchInput
|
31
|
+
v-bind="args"
|
32
|
+
@on-change="handleInputChange"
|
33
|
+
/>
|
34
|
+
`,
|
35
|
+
}
|
36
|
+
}
|
25
37
|
|
26
38
|
export const Default = Template.bind({})
|
27
39
|
Default.args = {
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
40
|
+
...defaultProps,
|
41
|
+
}
|
42
|
+
|
43
|
+
export const Placeholder = Template.bind({})
|
44
|
+
Placeholder.args = {
|
45
|
+
...defaultProps,
|
46
|
+
placeholder: 'Search... ',
|
32
47
|
}
|
33
48
|
|
34
49
|
export const Disabled = Template.bind({})
|
35
50
|
Disabled.args = {
|
36
|
-
|
51
|
+
...defaultProps,
|
37
52
|
disabled: true,
|
38
|
-
value: '',
|
39
|
-
inputWidth: '250px',
|
40
53
|
}
|
54
|
+
|
55
|
+
export const StyledIcon = Template.bind({})
|
56
|
+
StyledIcon.args = {
|
57
|
+
...defaultProps,
|
58
|
+
'icon-color': 'red',
|
59
|
+
'icon-position': 'left',
|
60
|
+
}
|
61
|
+
|
62
|
+
export const Sizes = Template.bind({})
|
63
|
+
Sizes.args = {
|
64
|
+
...defaultProps,
|
65
|
+
'input-width': '250px',
|
66
|
+
'is-filter': true,
|
67
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
const defaultSearchInputProps = {
|
2
|
+
dataId: 'search_input_id',
|
3
|
+
disabled: false, //
|
4
|
+
hasFocus: false, //
|
5
|
+
iconColor: 'black',
|
6
|
+
iconPosition: 'right',
|
7
|
+
inputWidth: null, //
|
8
|
+
isFilter: false,
|
9
|
+
placeholder: '',
|
10
|
+
value: '',
|
11
|
+
}
|
12
|
+
export default defaultSearchInputProps
|
@@ -22,15 +22,16 @@
|
|
22
22
|
// import SearchInput from "@eturnity/eturnity_reusable_components/src/components/inputs/searchInput"
|
23
23
|
// To use:
|
24
24
|
// <search-input
|
25
|
-
//
|
26
|
-
// :value="companyName"
|
25
|
+
// data-id='search_input_id'
|
27
26
|
// :disabled="true"
|
28
|
-
//
|
27
|
+
// :has-focus="true"
|
28
|
+
// icon-color="grey2" // colors only from theme
|
29
|
+
// icon-position="left"
|
30
|
+
// input-width="250px"
|
31
|
+
// :is-filter="true" // to set the height at 30px
|
32
|
+
// placeholder="Search by company name"
|
33
|
+
// :value="companyName"
|
29
34
|
// @on-change="function($event)"
|
30
|
-
// :isFilter="true" // to set the height at 30px
|
31
|
-
// data-id="test-data-id"
|
32
|
-
// iconPosition="left"
|
33
|
-
// iconColor="grey2"
|
34
35
|
// />
|
35
36
|
import styled from 'vue3-styled-components'
|
36
37
|
import SearchIconSvg from '../../../assets/icons/search_icon_black.svg'
|
@@ -94,31 +95,38 @@
|
|
94
95
|
},
|
95
96
|
props: {
|
96
97
|
value: {
|
98
|
+
type: [String, Number],
|
97
99
|
required: true,
|
98
100
|
},
|
99
101
|
disabled: {
|
100
102
|
required: false,
|
101
103
|
default: false,
|
104
|
+
type: Boolean,
|
102
105
|
},
|
103
106
|
placeholder: {
|
104
107
|
required: false,
|
105
108
|
default: '',
|
109
|
+
type: String,
|
106
110
|
},
|
107
111
|
inputWidth: {
|
108
112
|
required: false,
|
109
113
|
default: null,
|
114
|
+
type: String,
|
110
115
|
},
|
111
116
|
isFilter: {
|
112
117
|
required: false,
|
113
118
|
default: false,
|
119
|
+
type: Boolean,
|
114
120
|
},
|
115
121
|
hasFocus: {
|
116
122
|
required: false,
|
117
123
|
default: false,
|
124
|
+
type: Boolean,
|
118
125
|
},
|
119
126
|
dataId: {
|
120
127
|
required: false,
|
121
128
|
default: '',
|
129
|
+
type: [String, Number],
|
122
130
|
},
|
123
131
|
iconPosition: {
|
124
132
|
type: String,
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { mount } from '@vue/test-utils'
|
2
|
+
import SearchInput from '@/components/inputs/searchInput'
|
3
|
+
import defaultSearchInputProps from './defaultProps'
|
4
|
+
import theme from '@/assets/theme'
|
5
|
+
|
6
|
+
describe('SearchInput.vue', () => {
|
7
|
+
let searchInput
|
8
|
+
let searchInputWrapper
|
9
|
+
|
10
|
+
beforeEach(() => {
|
11
|
+
searchInput = mount(SearchInput, {
|
12
|
+
props: defaultSearchInputProps,
|
13
|
+
global: {
|
14
|
+
provide: {
|
15
|
+
theme,
|
16
|
+
},
|
17
|
+
},
|
18
|
+
})
|
19
|
+
|
20
|
+
const defaultDataId = searchInput.props('dataId')
|
21
|
+
searchInputWrapper = searchInput.find(`[data-id="${defaultDataId}"]`)
|
22
|
+
})
|
23
|
+
|
24
|
+
it('Search input is rendered and displays the correct placeholder', async () => {
|
25
|
+
// Check that Search input has been rendered
|
26
|
+
expect(searchInputWrapper.exists()).toBe(true)
|
27
|
+
|
28
|
+
// Set the placeholder
|
29
|
+
const placeholderText = 'Search by company name'
|
30
|
+
await searchInput.setProps({ placeholder: placeholderText })
|
31
|
+
await searchInput.vm.$nextTick()
|
32
|
+
|
33
|
+
// Check that the input displays the correct placeholder
|
34
|
+
expect(searchInputWrapper.attributes('placeholder')).toBe(placeholderText)
|
35
|
+
})
|
36
|
+
|
37
|
+
it('Search input emits correct payload on change', async () => {
|
38
|
+
// Simulate user input
|
39
|
+
const inputValue = 'test input'
|
40
|
+
await searchInputWrapper.setValue(inputValue)
|
41
|
+
|
42
|
+
// Check that the component emitted the 'on-change' event with correct payload
|
43
|
+
expect(searchInput.emitted('on-change')).toBeTruthy()
|
44
|
+
expect(searchInput.emitted('on-change')[0]).toEqual([inputValue])
|
45
|
+
})
|
46
|
+
|
47
|
+
it('test disabled prop', async () => {
|
48
|
+
await searchInput.setProps({ disabled: true })
|
49
|
+
await searchInput.vm.$nextTick()
|
50
|
+
|
51
|
+
expect(searchInputWrapper.attributes()).toHaveProperty('disabled')
|
52
|
+
expect(searchInputWrapper.element.disabled).toBe(true)
|
53
|
+
})
|
54
|
+
|
55
|
+
it('test hasFocus prop', async () => {
|
56
|
+
// Spy on the focus method
|
57
|
+
const focusSpy = jest.spyOn(searchInputWrapper.element, 'focus')
|
58
|
+
|
59
|
+
await searchInput.setProps({ hasFocus: true })
|
60
|
+
await searchInput.vm.$nextTick()
|
61
|
+
|
62
|
+
// Check that the focus method was called
|
63
|
+
expect(focusSpy).toHaveBeenCalled()
|
64
|
+
})
|
65
|
+
})
|
@@ -120,11 +120,6 @@
|
|
120
120
|
<SelectDropdown
|
121
121
|
v-show="isSelectDropdownShown"
|
122
122
|
ref="dropdown"
|
123
|
-
:style="{
|
124
|
-
transform: `translate(${dropdownPosition?.left}px, ${
|
125
|
-
noRelative ? 'auto' : `${dropdownPosition?.top}px`
|
126
|
-
})`,
|
127
|
-
}"
|
128
123
|
:bg-color="
|
129
124
|
dropdownBgColor || colorMode == 'dark' ? 'black' : 'white'
|
130
125
|
"
|
@@ -349,8 +344,9 @@
|
|
349
344
|
box-sizing: border-box;
|
350
345
|
z-index: ${(props) => (props.isActive ? '2' : '99999')};
|
351
346
|
position: absolute;
|
352
|
-
top:
|
353
|
-
|
347
|
+
top: ${(props) =>
|
348
|
+
props.noRelative ? 'auto' : props.dropdownPosition?.top + 'px'};
|
349
|
+
left: ${(props) => props.dropdownPosition?.left}px;
|
354
350
|
border: ${BORDER_WIDTH} solid ${(props) => props.theme.colors.grey4};
|
355
351
|
border-radius: 4px;
|
356
352
|
display: flex;
|
@@ -610,10 +606,6 @@
|
|
610
606
|
},
|
611
607
|
dropdownWidth: null,
|
612
608
|
hoveredValue: null,
|
613
|
-
isDisplayedAtBottom: true,
|
614
|
-
selectTopPosition: 0,
|
615
|
-
selectAndDropdownDistance: 0,
|
616
|
-
animationFrameId: null,
|
617
609
|
}
|
618
610
|
},
|
619
611
|
computed: {
|
@@ -684,13 +676,8 @@
|
|
684
676
|
}, 10)
|
685
677
|
await this.$nextTick()
|
686
678
|
this.handleSetDropdownOffet()
|
687
|
-
this.calculateSelectTopPosition()
|
688
679
|
} else {
|
689
680
|
this.dropdownPosition.left = null
|
690
|
-
if (this.animationFrameId) {
|
691
|
-
cancelAnimationFrame(this.animationFrameId)
|
692
|
-
this.animationFrameId = null
|
693
|
-
}
|
694
681
|
setTimeout(() => {
|
695
682
|
this.isClickOutsideActive = false
|
696
683
|
}, 10)
|
@@ -703,27 +690,11 @@
|
|
703
690
|
})
|
704
691
|
}
|
705
692
|
},
|
706
|
-
isSelectDropdownShown(isShown) {
|
707
|
-
if (!isShown) return
|
708
|
-
|
709
|
-
// Need to wait for 1ms to make sure the dropdown menu is shown in the DOM
|
710
|
-
// before getting the distance between the select and the dropdown menu
|
711
|
-
setTimeout(() => {
|
712
|
-
this.getDistanceBetweenSelectAndDropdownMenu()
|
713
|
-
}, 100)
|
714
|
-
},
|
715
|
-
selectTopPosition() {
|
716
|
-
this.dropdownPosition.top =
|
717
|
-
this.selectTopPosition +
|
718
|
-
this.$refs.select.$el.clientHeight +
|
719
|
-
this.selectAndDropdownDistance
|
720
|
-
},
|
721
693
|
},
|
722
694
|
mounted() {
|
723
695
|
this.observeDropdownHeight()
|
724
696
|
this.observeSelectWidth()
|
725
697
|
window.addEventListener('resize', this.handleSetDropdownOffet)
|
726
|
-
document.body.addEventListener('scroll', this.calculateSelectTopPosition)
|
727
698
|
},
|
728
699
|
beforeMount() {
|
729
700
|
this.selectedValue = this.value
|
@@ -732,10 +703,6 @@
|
|
732
703
|
window.removeEventListener('resize', this.handleSetDropdownOffet)
|
733
704
|
if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
|
734
705
|
if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
|
735
|
-
document.body.removeEventListener(
|
736
|
-
'scroll',
|
737
|
-
this.calculateSelectTopPosition
|
738
|
-
)
|
739
706
|
},
|
740
707
|
unmounted() {
|
741
708
|
document.removeEventListener('click', this.clickOutside)
|
@@ -841,11 +808,11 @@
|
|
841
808
|
return
|
842
809
|
}
|
843
810
|
await this.$nextTick()
|
844
|
-
|
811
|
+
const isDisplayedAtBottom = await this.generateDropdownPosition()
|
845
812
|
// If the dropdown menu is going to be displayed at the bottom,
|
846
813
|
// we need reverify its position after a dom update (nextTick)
|
847
814
|
await this.$nextTick()
|
848
|
-
if (
|
815
|
+
if (isDisplayedAtBottom) this.generateDropdownPosition()
|
849
816
|
},
|
850
817
|
async generateDropdownPosition() {
|
851
818
|
const isDropdownNotCompletelyVisible =
|
@@ -938,25 +905,6 @@
|
|
938
905
|
}
|
939
906
|
}
|
940
907
|
},
|
941
|
-
getDistanceBetweenSelectAndDropdownMenu() {
|
942
|
-
const wholeSelectTopPosition =
|
943
|
-
this.selectTopPosition + this.$refs.select.$el.clientHeight
|
944
|
-
this.selectAndDropdownDistance =
|
945
|
-
this.dropdownPosition.top - wholeSelectTopPosition
|
946
|
-
},
|
947
|
-
calculateSelectTopPosition() {
|
948
|
-
const selectRef = this.$refs.select
|
949
|
-
if (selectRef) {
|
950
|
-
const currentTopPosition =
|
951
|
-
selectRef.$el.getBoundingClientRect().top + window.scrollY
|
952
|
-
if (this.selectTopPosition !== currentTopPosition) {
|
953
|
-
this.selectTopPosition = currentTopPosition
|
954
|
-
}
|
955
|
-
}
|
956
|
-
this.animationFrameId = requestAnimationFrame(
|
957
|
-
this.calculateSelectTopPosition
|
958
|
-
)
|
959
|
-
},
|
960
908
|
},
|
961
909
|
}
|
962
910
|
</script>
|
@@ -35,37 +35,37 @@
|
|
35
35
|
visibility: ${(props) => (props.visible ? 'inherit' : 'hidden')};
|
36
36
|
`
|
37
37
|
|
38
|
-
const pageAttrs = { backdrop: String, position: String }
|
38
|
+
const pageAttrs = { isOpen: Boolean, backdrop: String, position: String }
|
39
39
|
const PageWrapper = styled('div', pageAttrs)`
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
40
|
+
position: ${(props) => props.position}
|
41
|
+
display: grid;
|
42
|
+
top: 0;
|
43
|
+
left: 0;
|
44
|
+
width: 100%;
|
45
|
+
height: 100%;
|
46
|
+
background-color: ${(props) =>
|
47
|
+
props.backdrop == 'dark'
|
48
|
+
? 'rgba(0, 0, 0, 0.4)'
|
49
|
+
: 'rgba(255, 255, 255, 0.9)'};
|
50
|
+
z-index: 99999;
|
51
|
+
overflow: auto;
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
&.visible {
|
54
|
+
visibility: visible;
|
55
|
+
opacity: 1;
|
56
|
+
transition: visibility 0s linear 0s, opacity 300ms;
|
57
|
+
}
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
&.hidden {
|
60
|
+
visibility: hidden;
|
61
|
+
opacity: 0;
|
62
|
+
transition: visibility 0s linear 300ms, opacity 300ms;
|
63
|
+
}
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
@media (max-width: 425px) {
|
66
|
+
background: white;
|
67
|
+
}
|
68
|
+
`
|
69
69
|
|
70
70
|
const ModalContainer = styled.div`
|
71
71
|
align-self: center;
|
@@ -94,7 +94,7 @@ export const stringToNumber = ({
|
|
94
94
|
|
95
95
|
export const numberToString = ({ value, numberPrecision, minDecimals }) => {
|
96
96
|
const minimumRounding = minDecimals ? minDecimals : 0
|
97
|
-
value =
|
97
|
+
value = parseFloat(value)
|
98
98
|
return value.toLocaleString(langForLocaleString(), {
|
99
99
|
minimumFractionDigits: minimumRounding, // removing this for now. Why do we need this to be a minimum amount?
|
100
100
|
maximumFractionDigits:
|