@eturnity/eturnity_reusable_components 8.16.5 → 8.16.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/refresh.svg +3 -0
- package/src/assets/theme.js +17 -1
- 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 +5 -0
- package/src/components/buttons/splitButtons/index.vue +86 -0
- package/src/components/collapsableInfoText/index.vue +2 -2
- package/src/components/icon/index.vue +14 -3
- package/src/components/inputs/inputNumber/index.vue +14 -2
- package/src/components/inputs/searchInput/index.vue +18 -2
- package/src/components/modals/modal/index.vue +1 -0
- package/src/helpers/isObjectEqual.js +22 -0
- package/src/main.js +1 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
import styled from 'vue3-styled-components'
|
2
|
+
|
3
|
+
export const Container = styled.div`
|
4
|
+
width: 100%;
|
5
|
+
`
|
6
|
+
|
7
|
+
export const LegendAndControlsWrapper = styled('div', { leftMargin: String })`
|
8
|
+
margin-left: ${(props) => props.leftMargin};
|
9
|
+
display: flex;
|
10
|
+
justify-content: space-between;
|
11
|
+
align-items: center;
|
12
|
+
`
|
13
|
+
|
14
|
+
export const LeftSection = styled.div`
|
15
|
+
flex: 1;
|
16
|
+
`
|
17
|
+
|
18
|
+
export const SplitButtonsContainer = styled('div', { position: String })`
|
19
|
+
align-self: ${(props) =>
|
20
|
+
props.position === 'top' ? 'flex-end' : 'flex-start'};
|
21
|
+
`
|
22
|
+
|
23
|
+
export const LegendGroups = styled.div`
|
24
|
+
display: flex;
|
25
|
+
flex-direction: column;
|
26
|
+
gap: 8px;
|
27
|
+
`
|
28
|
+
|
29
|
+
export const LegendRow = styled('div', { rowIndex: Number })`
|
30
|
+
display: flex;
|
31
|
+
gap: 10px;
|
32
|
+
align-items: center;
|
33
|
+
justify-content: ${(props) =>
|
34
|
+
props.rowIndex === 0 ? 'flex-start' : 'flex-end'};
|
35
|
+
`
|
36
|
+
|
37
|
+
export const LegendItem = styled.div`
|
38
|
+
display: flex;
|
39
|
+
align-items: center;
|
40
|
+
gap: 8px;
|
41
|
+
`
|
42
|
+
|
43
|
+
export const LegendColor = styled('div', {
|
44
|
+
gradientFrom: String,
|
45
|
+
gradientTo: String,
|
46
|
+
})`
|
47
|
+
width: 16px;
|
48
|
+
height: 16px;
|
49
|
+
border-radius: 4px;
|
50
|
+
background: ${(props) =>
|
51
|
+
`linear-gradient(180deg, ${props.gradientFrom} 0%, ${props.gradientTo} 100%)`};
|
52
|
+
`
|
53
|
+
|
54
|
+
export const LegendText = styled.span`
|
55
|
+
font-size: 12px;
|
56
|
+
font-weight: 400;
|
57
|
+
color: ${(props) => props.theme.semanticColors.teal[800]};
|
58
|
+
white-space: nowrap;
|
59
|
+
`
|
@@ -21,6 +21,7 @@
|
|
21
21
|
iconColor ||
|
22
22
|
theme.mainButton[appTheme][type][variant].default.textColor
|
23
23
|
"
|
24
|
+
:disable-hover="disableIconHover"
|
24
25
|
:hovered-color="
|
25
26
|
iconColor ||
|
26
27
|
theme.mainButton[appTheme][type][variant].default.textColor
|
@@ -231,6 +232,10 @@
|
|
231
232
|
default: false,
|
232
233
|
type: Boolean,
|
233
234
|
},
|
235
|
+
disableIconHover: {
|
236
|
+
type: Boolean,
|
237
|
+
default: false,
|
238
|
+
},
|
234
239
|
},
|
235
240
|
data() {
|
236
241
|
return {
|
@@ -0,0 +1,86 @@
|
|
1
|
+
<template>
|
2
|
+
<Container>
|
3
|
+
<SplitButton
|
4
|
+
v-for="(option, index) in options"
|
5
|
+
:data-id-key="`${dataIdKey}_${option.value}`"
|
6
|
+
:key="index"
|
7
|
+
:length="options.length"
|
8
|
+
:position="getButtonPosition(index)"
|
9
|
+
:selected="modelValue === option.value"
|
10
|
+
@click.stop="handleSelect(option.value)"
|
11
|
+
>
|
12
|
+
{{ option.label }}
|
13
|
+
</SplitButton>
|
14
|
+
</Container>
|
15
|
+
</template>
|
16
|
+
|
17
|
+
<script setup>
|
18
|
+
import styled from 'vue3-styled-components'
|
19
|
+
import { computed } from 'vue'
|
20
|
+
|
21
|
+
const Container = styled.div`
|
22
|
+
display: flex;
|
23
|
+
width: fit-content;
|
24
|
+
`
|
25
|
+
const SplitButton = styled('button', {
|
26
|
+
selected: Boolean,
|
27
|
+
position: String,
|
28
|
+
length: Number,
|
29
|
+
})`
|
30
|
+
padding: 8px 16px;
|
31
|
+
border: 1px solid ${(props) => props.theme.semanticColors.teal[100]};
|
32
|
+
${(props) =>
|
33
|
+
props.position === 'middle'
|
34
|
+
? `
|
35
|
+
border-left: none;
|
36
|
+
border-right: none;
|
37
|
+
`
|
38
|
+
: props.length === 2 && props.position === 'first'
|
39
|
+
? 'border-right: none;'
|
40
|
+
: ''}
|
41
|
+
border-radius: ${(props) =>
|
42
|
+
props.position === 'first'
|
43
|
+
? '4px 0 0 4px'
|
44
|
+
: props.position === 'last'
|
45
|
+
? '0 4px 4px 0'
|
46
|
+
: '0'};
|
47
|
+
font-family: ${(props) => props.theme.fonts.mainFont};
|
48
|
+
font-size: 14px;
|
49
|
+
font-weight: 400;
|
50
|
+
line-height: 100%;
|
51
|
+
cursor: pointer;
|
52
|
+
background: ${(props) =>
|
53
|
+
props.selected ? props.theme.semanticColors.purple[50] : 'transparent'};
|
54
|
+
color: ${(props) => props.theme.semanticColors.purple[500]};
|
55
|
+
`
|
56
|
+
|
57
|
+
const props = defineProps({
|
58
|
+
options: {
|
59
|
+
type: Array,
|
60
|
+
required: true,
|
61
|
+
// expects array of {label: string, value: string}
|
62
|
+
},
|
63
|
+
modelValue: {
|
64
|
+
type: String,
|
65
|
+
required: true,
|
66
|
+
},
|
67
|
+
dataIdKey: {
|
68
|
+
type: String,
|
69
|
+
default: '',
|
70
|
+
},
|
71
|
+
})
|
72
|
+
|
73
|
+
const emit = defineEmits(['update:modelValue'])
|
74
|
+
|
75
|
+
const getButtonPosition = computed(() => (index) => {
|
76
|
+
if (index === 0) return 'first'
|
77
|
+
if (index === props.options.length - 1) return 'last'
|
78
|
+
|
79
|
+
return 'middle'
|
80
|
+
})
|
81
|
+
|
82
|
+
const handleSelect = (value) => {
|
83
|
+
emit('update:modelValue', value)
|
84
|
+
emit('click', value)
|
85
|
+
}
|
86
|
+
</script>
|
@@ -33,7 +33,7 @@
|
|
33
33
|
const Text = styled('p', TextAttrs)`
|
34
34
|
display: block;
|
35
35
|
display: -webkit-box;
|
36
|
-
line-height: 1.
|
36
|
+
line-height: 1.5;
|
37
37
|
-webkit-line-clamp: ${(props) => (props.expand ? 'unset' : '4')};
|
38
38
|
-webkit-box-orient: vertical;
|
39
39
|
overflow: hidden;
|
@@ -49,7 +49,7 @@
|
|
49
49
|
const ToggleButton = styled('p', TextAttrs)`
|
50
50
|
font-size: ${(props) => props.fontSize}px;
|
51
51
|
cursor: pointer;
|
52
|
-
color: ${(props) => props.theme.
|
52
|
+
color: ${(props) => props.theme.semanticColors.purple[500]};
|
53
53
|
`
|
54
54
|
|
55
55
|
export default {
|
@@ -11,6 +11,7 @@
|
|
11
11
|
:background-color="backgroundColor"
|
12
12
|
:color="color"
|
13
13
|
data-test-id="icon_image"
|
14
|
+
:disable-hover="disableHover"
|
14
15
|
:fill-type="fillType"
|
15
16
|
:hovered-color="hoveredColor"
|
16
17
|
>
|
@@ -108,6 +109,10 @@
|
|
108
109
|
default: 'fill',
|
109
110
|
type: String,
|
110
111
|
},
|
112
|
+
disableHover: {
|
113
|
+
type: Boolean,
|
114
|
+
default: false,
|
115
|
+
},
|
111
116
|
})
|
112
117
|
|
113
118
|
const Wrapper = styled('div', {
|
@@ -164,6 +169,7 @@
|
|
164
169
|
hoveredColor: String,
|
165
170
|
animation: String,
|
166
171
|
fillType: String,
|
172
|
+
disableHover: Boolean,
|
167
173
|
}
|
168
174
|
const IconImage = styled('div', IconImageAttrs)`
|
169
175
|
animation: ${(props) => props.animation};
|
@@ -180,12 +186,17 @@
|
|
180
186
|
${({ theme, color, fillType }) =>
|
181
187
|
color && `${fillType}: ${theme.colors[color] || color};`}
|
182
188
|
}
|
183
|
-
|
184
|
-
|
189
|
+
${(props) =>
|
190
|
+
!props.disableHover &&
|
191
|
+
`
|
192
|
+
&:hover svg path:not(.fix) {
|
193
|
+
${`${props.fillType}: ${props.hoveredColor || props.color};`}
|
185
194
|
}
|
186
195
|
&:hover + div {
|
187
|
-
background-color: ${
|
196
|
+
background-color: ${props.hoveredColor};
|
188
197
|
}
|
198
|
+
`}
|
199
|
+
|
189
200
|
@keyframes fade {
|
190
201
|
50% {
|
191
202
|
opacity: 0.3;
|
@@ -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%')};
|
@@ -55,6 +61,7 @@
|
|
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: {
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { toRaw } from 'vue'
|
2
|
+
|
3
|
+
export default function isObjectEqual(obj1, obj2) {
|
4
|
+
obj1 = toRaw(obj1)
|
5
|
+
obj2 = toRaw(obj2)
|
6
|
+
if (obj1 === obj2) return true
|
7
|
+
if (obj1 === null || obj2 === null) return false
|
8
|
+
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false
|
9
|
+
|
10
|
+
const isArray1 = Array.isArray(obj1)
|
11
|
+
const isArray2 = Array.isArray(obj2)
|
12
|
+
if (isArray1 !== isArray2) return false
|
13
|
+
|
14
|
+
const keys1 = Object.keys(obj1)
|
15
|
+
if (keys1.length !== Object.keys(obj2).length) return false
|
16
|
+
|
17
|
+
return keys1.every(
|
18
|
+
(key) =>
|
19
|
+
Object.prototype.hasOwnProperty.call(obj2, key) &&
|
20
|
+
isObjectEqual(obj1[key], obj2[key])
|
21
|
+
)
|
22
|
+
}
|