@eturnity/eturnity_reusable_components 8.13.13-epic-shading.1 → 8.13.13-qa-16-03-26.1

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.
Files changed (34) hide show
  1. package/package.json +1 -1
  2. package/src/DemoCharts.vue +424 -0
  3. package/src/TestChart.vue +241 -0
  4. package/src/assets/svgIcons/refresh.svg +3 -0
  5. package/src/assets/theme.js +16 -1
  6. package/src/components/barchart/BottomFields.vue +253 -0
  7. package/src/components/barchart/ChartControls.vue +113 -0
  8. package/src/components/barchart/SelectionBox.vue +150 -0
  9. package/src/components/barchart/composables/index.js +5 -0
  10. package/src/components/barchart/composables/useAxisCalculations.js +104 -0
  11. package/src/components/barchart/composables/useChartData.js +114 -0
  12. package/src/components/barchart/composables/useChartScroll.js +61 -0
  13. package/src/components/barchart/composables/useSelection.js +75 -0
  14. package/src/components/barchart/composables/useTooltip.js +100 -0
  15. package/src/components/barchart/index.vue +376 -0
  16. package/src/components/barchart/styles/bottomFields.js +66 -0
  17. package/src/components/barchart/styles/chart.js +259 -0
  18. package/src/components/barchart/styles/chartControls.js +59 -0
  19. package/src/components/buttons/splitButtons/index.vue +86 -0
  20. package/src/components/collapsableInfoText/index.vue +2 -2
  21. package/src/components/inputs/checkbox/index.vue +2 -2
  22. package/src/components/inputs/inputNumber/index.vue +78 -80
  23. package/src/components/inputs/select/index.vue +89 -16
  24. package/src/components/modals/modal/index.vue +15 -5
  25. package/src/helpers/isObjectEqual.js +22 -0
  26. package/src/helpers/numberConverter.js +1 -1
  27. package/src/main.js +8 -0
  28. package/src/router/dynamicRoutes.js +12 -0
  29. package/src/assets/icons/collapse_arrow_icon_white.svg +0 -1
  30. package/src/assets/svgIcons/house_sun.svg +0 -3
  31. package/src/components/draggableCard/defaultProps.js +0 -16
  32. package/src/components/draggableCard/draggableCard.spec.js +0 -99
  33. package/src/components/draggableCard/draggableCard.stories.js +0 -79
  34. package/src/components/draggableCard/index.vue +0 -363
@@ -0,0 +1,376 @@
1
+ <template>
2
+ <Container :class="`barchart-${chartId}`" :width="width">
3
+ <ChartControlsWrapper
4
+ v-if="isChartControlsShown('top')"
5
+ :position="chartControlsPosition"
6
+ >
7
+ <ChartControls
8
+ :is-legend-shown="isLegendShown"
9
+ :legends-item-per-row="legendsItemPerRow"
10
+ :position="chartControlsPosition"
11
+ :selected-split-button="selectedSplitButton"
12
+ :series="series"
13
+ :split-button-options="splitButtonOptions"
14
+ :stacked-colors="getStackedColors"
15
+ :y-axis-width="yAxisWidth"
16
+ @select-split-button="handleSelectSplitButton"
17
+ />
18
+ </ChartControlsWrapper>
19
+ <GraphSection :height="height" :width="width">
20
+ <YAxis :width="yAxisWidth" :height="height">
21
+ <YAxisTitleWrapper v-if="yAxisTitle" :height="yAxisHeight">
22
+ {{ yAxisTitle }}
23
+ </YAxisTitleWrapper>
24
+ <YAxisRow
25
+ v-for="label in yAxisLabels"
26
+ :key="label"
27
+ :percentage="
28
+ Number(
29
+ ((label / yAxisLabels[yAxisLabels.length - 1]) * 100).toFixed(4)
30
+ )
31
+ "
32
+ >
33
+ <YAxisLabel>{{ label }}</YAxisLabel>
34
+ <YAxisLine :y-axis-width="yAxisWidth" />
35
+ </YAxisRow>
36
+ </YAxis>
37
+
38
+ <ScrollContainer
39
+ :class="`chart-scroll-container-${chartId}`"
40
+ :is-scrollable="isScrollable"
41
+ :height="height"
42
+ @scroll="handleChartScroll"
43
+ >
44
+ <ChartContent
45
+ ref="chartContent"
46
+ :bar-width="barWidth"
47
+ :height="height"
48
+ :is-scrollable="isScrollable"
49
+ :total-bars="normalizedData.length"
50
+ >
51
+ <SelectionBox
52
+ v-if="selectionSize && isSelectionEnabled"
53
+ :bar-width="barWidth"
54
+ :bars-to-show="selectionSize"
55
+ :container-width="chartContentWidth"
56
+ :is-scrollable="isScrollable"
57
+ :total-bars="normalizedData.length"
58
+ @drag-end="handleSelectionDragEnd"
59
+ @update-selection="updateSelectedBars"
60
+ />
61
+ <BarsContainer>
62
+ <BarGroup
63
+ v-for="(item, index) in normalizedData"
64
+ :bar-width="barWidth"
65
+ class="bar-group"
66
+ :is-scrollable="isScrollable"
67
+ :key="index"
68
+ >
69
+ <BarWrapper>
70
+ <BarSegment
71
+ v-for="(segment, segIndex) in item.segments"
72
+ class="bar-segment"
73
+ :gradient-from="getSegmentGradient(index, segment).from"
74
+ :gradient-to="getSegmentGradient(index, segment).to"
75
+ :height="`${segment.percentage}%`"
76
+ :key="segIndex"
77
+ :z-index="item.segments.length - segIndex"
78
+ @mouseenter="showTooltip(item, $event, series)"
79
+ @mouseleave="hideTooltip"
80
+ />
81
+ </BarWrapper>
82
+ <XAxisLine />
83
+ <XAxisLabelHighlight v-if="isSelectionBoundary(index)">
84
+ {{ item.label }}
85
+ </XAxisLabelHighlight>
86
+ <XAxisLabel v-else>{{ item.label }}</XAxisLabel>
87
+ </BarGroup>
88
+ </BarsContainer>
89
+ </ChartContent>
90
+ </ScrollContainer>
91
+ <Tooltip
92
+ v-if="showTooltipContent"
93
+ :left="tooltipStyle.left"
94
+ :top="tooltipStyle.top"
95
+ >
96
+ <slot :item="tooltipData" name="tooltip" />
97
+ <TooltipTextWrapper v-if="!slots.tooltip && tooltipData">
98
+ <template v-if="!series.length">
99
+ <TooltipText font-weight="500">{{ tooltipData.label }}</TooltipText>
100
+ <TooltipText>
101
+ {{ handleValueFormatter(tooltipData.segments[0].value) }}
102
+ </TooltipText>
103
+ </template>
104
+
105
+ <template v-else>
106
+ <TooltipRow>
107
+ <TooltipText font-weight="500">{{
108
+ tooltipData.label
109
+ }}</TooltipText>
110
+ <TooltipText>
111
+ {{
112
+ handleValueFormatter(
113
+ getTotalSegmentValue(tooltipData.segments)
114
+ )
115
+ }}
116
+ </TooltipText>
117
+ </TooltipRow>
118
+ <template
119
+ v-for="(segment, index) in [...tooltipData.segments].reverse()"
120
+ :key="index"
121
+ >
122
+ <TooltipRow>
123
+ <TooltipGradientBox
124
+ :gradient-from="segment.gradientFrom"
125
+ :gradient-to="segment.gradientTo"
126
+ />
127
+ <TooltipText>
128
+ {{ handleValueFormatter(segment.value) }}
129
+ </TooltipText>
130
+ </TooltipRow>
131
+ </template>
132
+ </template>
133
+ </TooltipTextWrapper>
134
+ </Tooltip>
135
+ </GraphSection>
136
+ <ChartControlsWrapper
137
+ v-if="isChartControlsShown('bottom')"
138
+ :position="chartControlsPosition"
139
+ >
140
+ <ChartControls
141
+ :is-legend-shown="isLegendShown"
142
+ :legends-item-per-row="legendsItemPerRow"
143
+ :position="chartControlsPosition"
144
+ :selected-split-button="selectedSplitButton"
145
+ :series="series"
146
+ :split-button-options="splitButtonOptions"
147
+ :stacked-colors="getStackedColors"
148
+ :y-axis-width="yAxisWidth"
149
+ @select-split-button="handleSelectSplitButton"
150
+ />
151
+ </ChartControlsWrapper>
152
+ <BottomFields
153
+ v-if="isBottomFieldsShown"
154
+ :bar-width="barWidth"
155
+ :chart-id="chartId"
156
+ :data="data"
157
+ :field-mode="fieldMode"
158
+ :is-chart-controls-shown-in-bottom="isChartControlsShown('bottom')"
159
+ :is-scrollable="isScrollable"
160
+ :series="series"
161
+ :y-axis-width="yAxisWidth"
162
+ @input-blur="handleInputBlur"
163
+ @input-blur-all="handleInputBlurAll"
164
+ @input-focus="showTooltipFromInput"
165
+ @sync-scroll="handleBottomFieldsScroll"
166
+ />
167
+ </Container>
168
+ </template>
169
+
170
+ <script setup>
171
+ import { useSlots, computed } from 'vue'
172
+
173
+ import ChartControls from './ChartControls'
174
+ import BottomFields from './BottomFields'
175
+ import SelectionBox from './SelectionBox'
176
+
177
+ import {
178
+ useTooltip,
179
+ useChartData,
180
+ useAxisCalculations,
181
+ useSelection,
182
+ useChartScroll,
183
+ } from './composables'
184
+
185
+ import {
186
+ Container,
187
+ GraphSection,
188
+ YAxis,
189
+ YAxisRow,
190
+ YAxisLabel,
191
+ YAxisLine,
192
+ YAxisTitleWrapper,
193
+ ScrollContainer,
194
+ ChartContent,
195
+ BarsContainer,
196
+ BarGroup,
197
+ BarWrapper,
198
+ BarSegment,
199
+ XAxisLabel,
200
+ XAxisLabelHighlight,
201
+ XAxisLine,
202
+ Tooltip,
203
+ TooltipText,
204
+ TooltipTextWrapper,
205
+ TooltipRow,
206
+ TooltipGradientBox,
207
+ ChartControlsWrapper,
208
+ } from './styles/chart'
209
+
210
+ const props = defineProps({
211
+ data: {
212
+ type: Array,
213
+ default: () => [],
214
+ validator: (value, ...args) => value.every((item) => 'label' in item),
215
+ },
216
+ series: {
217
+ type: Array,
218
+ default: () => [],
219
+ validator: (value) =>
220
+ value.every(
221
+ (item) => 'name' in item && 'data' in item && Array.isArray(item.data)
222
+ ),
223
+ },
224
+ width: {
225
+ type: String,
226
+ default: '100%',
227
+ },
228
+ height: {
229
+ type: String,
230
+ default: '400px',
231
+ },
232
+ barWidth: {
233
+ type: Number,
234
+ default: 60,
235
+ },
236
+ steps: {
237
+ type: Number,
238
+ default: null,
239
+ },
240
+ yAxisTitle: {
241
+ type: String,
242
+ default: '',
243
+ },
244
+ valueFormatter: {
245
+ type: Function,
246
+ default: null,
247
+ },
248
+ isLegendShown: {
249
+ type: Boolean,
250
+ default: false,
251
+ },
252
+ legendsItemPerRow: {
253
+ type: Number,
254
+ default: 4,
255
+ },
256
+ chartControlsPosition: {
257
+ type: String,
258
+ default: 'top',
259
+ validator: (value) => ['top', 'bottom'].includes(value),
260
+ },
261
+ splitButtonOptions: {
262
+ type: Array,
263
+ default: () => [],
264
+ },
265
+ selectedSplitButton: {
266
+ type: String,
267
+ default: '',
268
+ },
269
+ isScrollable: {
270
+ type: Boolean,
271
+ default: true,
272
+ },
273
+ isBottomFieldsShown: {
274
+ type: Boolean,
275
+ default: false,
276
+ },
277
+ selectionSize: {
278
+ type: Number,
279
+ default: 0,
280
+ },
281
+ isSelectionEnabled: {
282
+ type: Boolean,
283
+ default: false,
284
+ },
285
+ fieldMode: {
286
+ type: String,
287
+ default: 'absolute',
288
+ validator: (value) => ['absolute', 'percentage'].includes(value),
289
+ },
290
+ })
291
+
292
+ const generateChartId = () =>
293
+ `chart-${Date.now()}-${Math.floor(Math.random() * 1000)}`
294
+ const chartId = generateChartId()
295
+
296
+ const maxDataValue = computed(() => {
297
+ if (!props.data.length) return 0
298
+
299
+ return Math.max(
300
+ ...props.data.map((item) =>
301
+ props.series.length
302
+ ? props.series.reduce(
303
+ (sum, series) =>
304
+ sum +
305
+ (series.data.find((d) => d.label === item.label)?.value || 0),
306
+ 0
307
+ )
308
+ : item.value
309
+ )
310
+ )
311
+ })
312
+
313
+ const {
314
+ yAxisLabels,
315
+ yAxisHeight,
316
+ yAxisWidth,
317
+ isChartControlsShown,
318
+ paddedMaxValue,
319
+ } = useAxisCalculations(props, maxDataValue)
320
+
321
+ const { normalizedData, getStackedColors, getTotalSegmentValue } =
322
+ useChartData(props, paddedMaxValue)
323
+
324
+ const {
325
+ updateSelectedBars,
326
+ handleSelectionDragEnd,
327
+ isSelectionBoundary,
328
+ getSegmentGradient,
329
+ } = useSelection(props, normalizedData, emit)
330
+
331
+ const {
332
+ showTooltipContent,
333
+ showTooltip,
334
+ hideTooltip,
335
+ tooltipData,
336
+ tooltipStyle,
337
+ isInputFocused,
338
+ focusedBarData,
339
+ showTooltipFromInput,
340
+ handleInputBlurAll,
341
+ } = useTooltip(chartId, normalizedData)
342
+
343
+ const {
344
+ chartContent,
345
+ chartContentWidth,
346
+ handleChartScroll,
347
+ handleBottomFieldsScroll,
348
+ } = useChartScroll(
349
+ chartId,
350
+ isInputFocused,
351
+ focusedBarData,
352
+ showTooltipFromInput
353
+ )
354
+
355
+ const emit = defineEmits([
356
+ 'select-split-button',
357
+ 'selection-change',
358
+ 'input-blur',
359
+ ])
360
+
361
+ const slots = useSlots()
362
+
363
+ const handleSelectSplitButton = (value) => {
364
+ emit('select-split-button', value)
365
+ }
366
+
367
+ const handleInputBlur = (payload) => {
368
+ emit('input-blur', payload)
369
+ }
370
+
371
+ const handleValueFormatter = (value) => {
372
+ return props.valueFormatter
373
+ ? props.valueFormatter(Math.round(value))
374
+ : value
375
+ }
376
+ </script>
@@ -0,0 +1,66 @@
1
+ import styled from 'vue3-styled-components'
2
+
3
+ export const Container = styled('div', {
4
+ isChartControlsShownInBottom: Boolean,
5
+ })`
6
+ display: flex;
7
+ margin-top: ${(props) =>
8
+ props.isChartControlsShownInBottom ? '20px' : '44px'};
9
+ `
10
+
11
+ export const LabelsColumn = styled('div', { width: String })`
12
+ width: ${(props) => props.width};
13
+ display: flex;
14
+ flex-direction: column;
15
+ gap: 12px;
16
+ `
17
+
18
+ export const LabelRow = styled.div`
19
+ height: 32px;
20
+ font-size: 12px;
21
+ font-weight: 500;
22
+ color: ${(props) => props.theme.semanticColors.teal[600]};
23
+ display: flex;
24
+ align-items: flex-start;
25
+ `
26
+
27
+ export const TotalRow = styled(LabelRow)``
28
+
29
+ export const FieldsContainer = styled.div`
30
+ flex: 1;
31
+ overflow-x: auto;
32
+ scrollbar-width: none;
33
+
34
+ &::-webkit-scrollbar {
35
+ display: none;
36
+ }
37
+ `
38
+
39
+ export const FieldsWrapper = styled.div`
40
+ display: flex;
41
+ flex-direction: column;
42
+ gap: 8px;
43
+ `
44
+
45
+ export const InputRow = styled.div`
46
+ display: flex;
47
+ align-items: center;
48
+ justify-content: space-around;
49
+ gap: 8px;
50
+ padding-left: 12px;
51
+ padding-right: 12px;
52
+ `
53
+
54
+ export const TotalInputRow = styled(InputRow)`
55
+ margin-top: 0;
56
+ `
57
+
58
+ export const InputGroup = styled('div', {
59
+ barWidth: Number,
60
+ isScrollable: Boolean,
61
+ })`
62
+ ${(props) => (props.isScrollable ? 'min-width' : 'width')}:${(props) =>
63
+ props.barWidth}px;
64
+ display: flex;
65
+ justify-content: center;
66
+ `
@@ -0,0 +1,259 @@
1
+ import styled from 'vue3-styled-components'
2
+ import theme from '@/assets/theme'
3
+
4
+ export const Container = styled('div', { width: String })`
5
+ display: flex;
6
+ flex-direction: column;
7
+ padding-top: 40px;
8
+ font-family: ${(props) => props.theme.fonts.mainFont};
9
+ width: ${(props) => props.width};
10
+ `
11
+
12
+ export const GraphSection = styled('div', { width: String, height: String })`
13
+ height: ${(props) => props.height};
14
+ width: ${(props) => props.width};
15
+ position: relative;
16
+ display: flex;
17
+ `
18
+
19
+ export const YAxis = styled('div', { width: String, height: String })`
20
+ width: ${(props) => props.width};
21
+ display: flex;
22
+ flex-direction: column;
23
+ position: relative;
24
+ height: ${(props) => props.height};
25
+ `
26
+
27
+ export const YAxisRow = styled('div', { percentage: Number })`
28
+ display: flex;
29
+ align-items: center;
30
+ width: 100%;
31
+ position: absolute;
32
+ height: 0;
33
+ bottom: ${(props) =>
34
+ Number.isFinite(props.percentage) ? `${props.percentage}%` : '0'};
35
+ transform: translateY(50%);
36
+ `
37
+
38
+ export const YAxisLabel = styled.div`
39
+ font-size: 12px;
40
+ color: ${(props) => props.theme.semanticColors.teal[600]};
41
+ width: 100%;
42
+ text-align: right;
43
+ padding-right: 16px;
44
+ position: relative;
45
+ z-index: 1;
46
+ `
47
+
48
+ export const YAxisLine = styled('div', { yAxisWidth: String })`
49
+ position: absolute;
50
+ right: -10px;
51
+ left: calc(${(props) => props.yAxisWidth} - 10px);
52
+ height: 1px;
53
+ background-color: rgba(0, 0, 0, 0.1);
54
+ width: 12px;
55
+ z-index: 0;
56
+ top: 50%;
57
+ transform: translateY(-50%);
58
+ `
59
+
60
+ export const YAxisTitleWrapper = styled('div', { height: String })`
61
+ position: absolute;
62
+ left: -66px;
63
+ top: ${(props) => props.height};
64
+ transform: rotate(-90deg) translateX(50%);
65
+ transform-origin: right;
66
+ font-size: 12px;
67
+ color: ${(props) => props.theme.semanticColors.teal[600]};
68
+ display: flex;
69
+ align-items: center;
70
+ white-space: nowrap;
71
+ font-family: ${(props) => props.theme.fonts.mainFont};
72
+ `
73
+
74
+ export const ScrollContainer = styled('div', {
75
+ isScrollable: Boolean,
76
+ height: String,
77
+ })`
78
+ flex: 1;
79
+ overflow-x: auto;
80
+ overflow-y: hidden;
81
+ height: calc(${(props) => props.height} + 30px);
82
+ `
83
+
84
+ export const ChartContent = styled('div', {
85
+ totalBars: Number,
86
+ barWidth: Number,
87
+ isScrollable: Boolean,
88
+ height: String,
89
+ })`
90
+ height: ${(props) => props.height};
91
+ position: relative;
92
+ background: ${(props) => props.theme.semanticColors.grey[100]};
93
+ ${(props) =>
94
+ props.isScrollable
95
+ ? ` min-width: ${props.totalBars * (props.barWidth + 8) + 24}px;`
96
+ : 'width: 100%;'}
97
+ `
98
+
99
+ export const BarsContainer = styled.div`
100
+ height: 100%;
101
+ display: flex;
102
+ align-items: flex-end;
103
+ justify-content: space-around;
104
+ gap: 8px;
105
+ padding-left: 12px;
106
+ padding-right: 12px;
107
+ position: relative;
108
+ z-index: 1;
109
+ pointer-events: none;
110
+ `
111
+
112
+ export const BarGroup = styled('div', {
113
+ barWidth: Number,
114
+ isScrollable: Boolean,
115
+ })`
116
+ display: flex;
117
+ flex-direction: column;
118
+ align-items: center;
119
+ height: 100%;
120
+ position: relative;
121
+ ${(props) => (props.isScrollable ? 'min-width' : 'width')}:${(props) =>
122
+ props.barWidth}px;
123
+ pointer-events: none;
124
+ `
125
+
126
+ export const BarWrapper = styled.div`
127
+ height: 100%;
128
+ width: 100%;
129
+ position: relative;
130
+ `
131
+
132
+ export const BarSegment = styled('div', {
133
+ gradientFrom: String,
134
+ gradientTo: String,
135
+ height: String,
136
+ zIndex: Number,
137
+ })`
138
+ position: absolute;
139
+ bottom: 0;
140
+ left: 0;
141
+ right: 0;
142
+ height: ${(props) => props.height};
143
+ z-index: ${(props) => props.zIndex};
144
+ transition: opacity 0.2s;
145
+ border-radius: 8px 8px 0 0;
146
+ background: ${(props) =>
147
+ `linear-gradient(180deg, ${props.gradientFrom} 0%, ${props.gradientTo} 100%)`};
148
+ transform-origin: bottom;
149
+ will-change: transform, height;
150
+ pointer-events: auto;
151
+ &:hover {
152
+ opacity: 0.8;
153
+ }
154
+ `
155
+
156
+ export const XAxisLabel = styled.div`
157
+ font-size: 12px;
158
+ color: ${(props) => props.theme.semanticColors.teal[600]};
159
+ position: absolute;
160
+ bottom: -12px;
161
+ transform: translateY(100%);
162
+ user-select: none;
163
+ `
164
+
165
+ export const XAxisLabelHighlight = styled.div`
166
+ background: ${theme.semanticColors.purple[500]};
167
+ color: white;
168
+ padding: 4px;
169
+ border-radius: 4px;
170
+ font-size: 12px;
171
+ position: absolute;
172
+ bottom: -8px;
173
+ transform: translateY(100%);
174
+ user-select: none;
175
+ text-align: center;
176
+ `
177
+
178
+ export const XAxisLine = styled.div`
179
+ width: 1px;
180
+ height: 6px;
181
+ background-color: rgba(0, 0, 0, 0.1);
182
+ position: absolute;
183
+ bottom: -6px;
184
+ left: 50%;
185
+ transform: translateX(-50%);
186
+ `
187
+
188
+ export const Tooltip = styled('div', {
189
+ top: String,
190
+ left: String,
191
+ })`
192
+ position: fixed;
193
+ top: ${(props) => props.top};
194
+ left: ${(props) => props.left};
195
+ background: rgba(0, 0, 0, 0.8);
196
+ color: white;
197
+ padding: 4px 6px;
198
+ border-radius: 4px;
199
+ font-size: 14px;
200
+ pointer-events: none;
201
+ transform: translate(-50%, -100%);
202
+ z-index: 1000;
203
+ margin-top: -10px;
204
+
205
+ &::after {
206
+ content: '';
207
+ position: absolute;
208
+ bottom: -6px;
209
+ left: 50%;
210
+ transform: translateX(-50%);
211
+ border-left: 4px solid transparent;
212
+ border-right: 4px solid transparent;
213
+ border-top: 6px solid rgba(0, 0, 0, 0.8);
214
+ width: 0;
215
+ height: 0;
216
+ }
217
+ `
218
+
219
+ export const TooltipText = styled('div', {
220
+ fontWeight: String,
221
+ })`
222
+ font-weight: ${(props) => props.fontWeight || '400'};
223
+ font-size: 12px;
224
+ `
225
+
226
+ export const TooltipTextWrapper = styled.div`
227
+ display: flex;
228
+ flex-direction: column;
229
+ gap: 4px;
230
+ `
231
+
232
+ export const TooltipRow = styled.div`
233
+ width: 100px;
234
+ display: flex;
235
+ flex-direction: row;
236
+ justify-content: space-between;
237
+ align-items: center;
238
+ `
239
+
240
+ export const TooltipGradientBox = styled('div', {
241
+ gradientFrom: String,
242
+ gradientTo: String,
243
+ })`
244
+ background: ${(props) =>
245
+ `linear-gradient(180deg, ${props.gradientFrom} 0%, ${props.gradientTo} 100%)`};
246
+ width: 12px;
247
+ height: 12px;
248
+ border-radius: 4px;
249
+ `
250
+
251
+ export const ChartControlsWrapper = styled('div', { position: String })`
252
+ ${(props) =>
253
+ props.position === 'top' ? 'margin-bottom: 6px;' : 'margin-top: 36px;'}
254
+ `
255
+
256
+ export const BottomFieldsContainer = styled.div`
257
+ margin-top: 16px;
258
+ width: 100%;
259
+ `