@oliasoft-open-source/charts-library 3.3.6-beta-3 → 3.3.6-beta-5

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 (99) hide show
  1. package/index.js +14 -0
  2. package/package.json +1 -6
  3. package/release-notes.md +378 -0
  4. package/src/assets/circle.svg +1 -0
  5. package/src/assets/icons/line-and-point.svg +1 -0
  6. package/src/assets/icons/line-only.svg +1 -0
  7. package/src/assets/icons/list-hide.svg +1 -0
  8. package/src/assets/icons/point-only.svg +1 -0
  9. package/src/assets/rect.svg +1 -0
  10. package/src/assets/rectRot.svg +1 -0
  11. package/src/assets/triangle.svg +1 -0
  12. package/src/components/bar-chart/bar-chart-prop-types.js +209 -0
  13. package/src/components/bar-chart/bar-chart.interface.ts +98 -0
  14. package/src/components/bar-chart/bar-chart.jsx +247 -0
  15. package/src/components/bar-chart/bar-chart.module.less +61 -0
  16. package/src/components/bar-chart/get-bar-chart-data-labels.js +42 -0
  17. package/src/components/bar-chart/get-bar-chart-scales.js +138 -0
  18. package/src/components/bar-chart/get-bar-chart-tooltips.js +102 -0
  19. package/src/components/controls/axes-options/axes-options.jsx +271 -0
  20. package/src/components/line-chart/constants/default-translations.js +24 -0
  21. package/src/components/line-chart/constants/line-chart-consts.js +12 -0
  22. package/src/components/line-chart/controls/axes-options/action-types.js +5 -0
  23. package/src/components/line-chart/controls/axes-options/axes-options-form-state.js +97 -0
  24. package/src/components/line-chart/controls/controls-portal.jsx +12 -0
  25. package/src/components/line-chart/controls/controls.jsx +176 -0
  26. package/src/components/line-chart/controls/controls.module.less +12 -0
  27. package/src/components/line-chart/controls/drag-options.jsx +124 -0
  28. package/src/components/line-chart/controls/line-options.jsx +64 -0
  29. package/src/components/line-chart/hooks/use-chart-functions.js +261 -0
  30. package/src/components/line-chart/hooks/use-chart-options.js +181 -0
  31. package/src/components/line-chart/hooks/use-chart-plugins.js +35 -0
  32. package/src/components/line-chart/hooks/use-toggle-handler.js +33 -0
  33. package/src/components/line-chart/initialize/config.js +23 -0
  34. package/src/components/line-chart/initialize/initialize-line-chart.js +25 -0
  35. package/src/components/line-chart/legend/legend-constants.js +1 -0
  36. package/src/components/line-chart/legend/legend-dropzone.jsx +74 -0
  37. package/src/components/line-chart/legend/legend-item.jsx +105 -0
  38. package/src/components/line-chart/legend/legend-panel.jsx +86 -0
  39. package/src/components/line-chart/legend/legend.jsx +54 -0
  40. package/src/components/line-chart/legend/legend.module.less +192 -0
  41. package/src/components/line-chart/line-chart-prop-types.js +298 -0
  42. package/src/components/line-chart/line-chart.interface.ts +128 -0
  43. package/src/components/line-chart/line-chart.jsx +180 -0
  44. package/src/components/line-chart/line-chart.module.less +78 -0
  45. package/src/components/line-chart/plugins/chart-area-text-plugin.js +246 -0
  46. package/src/components/line-chart/plugins/line-chart.minor-gridlines-plugin.js +88 -0
  47. package/src/components/line-chart/plugins/plugin-constants.js +11 -0
  48. package/src/components/line-chart/state/action-types.js +12 -0
  49. package/src/components/line-chart/state/initial-state.js +89 -0
  50. package/src/components/line-chart/state/line-chart-reducer.js +101 -0
  51. package/src/components/line-chart/state/manage-state-in-local-storage.js +86 -0
  52. package/src/components/line-chart/state/use-chart-state.js +141 -0
  53. package/src/components/line-chart/utils/axis-formatting/axis-formatting.js +69 -0
  54. package/src/components/line-chart/utils/axis-scales/axis-scales.js +165 -0
  55. package/src/components/line-chart/utils/datalabels-alignment/get-alignment-condition.js +13 -0
  56. package/src/components/line-chart/utils/datalabels-alignment/get-alignment-data.js +20 -0
  57. package/src/components/line-chart/utils/datalabels-alignment/get-datalabels-position.js +25 -0
  58. package/src/components/line-chart/utils/generate-line-chart-datasets.js +122 -0
  59. package/src/components/line-chart/utils/get-axes-ranges-from-chart.js +13 -0
  60. package/src/components/line-chart/utils/get-line-chart-data-labels.js +21 -0
  61. package/src/components/line-chart/utils/get-line-chart-scales.js +117 -0
  62. package/src/components/line-chart/utils/get-line-chart-tooltips.js +94 -0
  63. package/src/components/line-chart/utils/line-chart-utils.js +62 -0
  64. package/src/components/line-chart/utils/translations/get-translations.js +17 -0
  65. package/src/components/pie-chart/pie-chart-prop-types.js +111 -0
  66. package/src/components/pie-chart/pie-chart-utils.js +32 -0
  67. package/src/components/pie-chart/pie-chart.interface.ts +61 -0
  68. package/src/components/pie-chart/pie-chart.jsx +458 -0
  69. package/src/components/pie-chart/pie-chart.module.less +61 -0
  70. package/src/components/scatter-chart/scatter-chart.intefrace.ts +33 -0
  71. package/src/components/scatter-chart/scatter-chart.jsx +21 -0
  72. package/src/components/scatter-chart/scatter-chart.module.less +4 -0
  73. package/src/helpers/chart-border-plugin.js +19 -0
  74. package/src/helpers/chart-consts.js +64 -0
  75. package/src/helpers/chart-interface.ts +94 -0
  76. package/src/helpers/chart-utils.js +178 -0
  77. package/src/helpers/container.jsx +60 -0
  78. package/src/helpers/disabled-context.js +8 -0
  79. package/src/helpers/enums.js +107 -0
  80. package/src/helpers/get-chart-annotation.js +102 -0
  81. package/src/helpers/get-custom-legend-plugin-example.js +80 -0
  82. package/src/helpers/get-draggableData.js +32 -0
  83. package/src/helpers/range/estimate-data-series-have-close-values.js +54 -0
  84. package/src/helpers/range/range.js +100 -0
  85. package/src/helpers/text.js +6 -0
  86. package/src/style/external.less +4 -0
  87. package/src/style/fonts/lato/Lato-Bold.woff2 +0 -0
  88. package/src/style/fonts/lato/Lato-BoldItalic.woff2 +0 -0
  89. package/src/style/fonts/lato/Lato-Italic.woff2 +0 -0
  90. package/src/style/fonts/lato/Lato-Regular.woff2 +0 -0
  91. package/src/style/fonts.less +27 -0
  92. package/src/style/global.less +43 -0
  93. package/src/style/reset/reset.less +28 -0
  94. package/src/style/shared.less +11 -0
  95. package/src/style/variables.less +91 -0
  96. package/vite.config.mjs +49 -0
  97. package/vitest.config.mjs +8 -0
  98. package/dist/index.js +0 -39189
  99. package/dist/index.js.map +0 -1
@@ -0,0 +1,23 @@
1
+ import { INIT_KEYS } from '../constants/line-chart-consts';
2
+ import { getTranslations } from '../utils/translations/get-translations';
3
+
4
+ const config = {
5
+ [INIT_KEYS.TRANSLATIONS]: getTranslations(),
6
+ [INIT_KEYS.LANGUAGE_KEY]: 'en',
7
+ };
8
+
9
+ /**
10
+ * Retrieve the value for the given key from the config object.
11
+ * @param {string} key - The key to access the corresponding value in the config object.
12
+ * @returns {*} - The value associated with the given key in the config object or config.
13
+ */
14
+ export const getConfig = (key) => (key ? config[key] : config);
15
+
16
+ /**
17
+ * Set a new value for the given key in the config object.
18
+ * @param {string} key - The key to access the corresponding value in the config object.
19
+ * @param {*} newValue - The new value to be set for the given key.
20
+ */
21
+ export const setConfig = (key, newValue) => {
22
+ config[key] = newValue;
23
+ };
@@ -0,0 +1,25 @@
1
+ import { INIT_KEYS } from '../constants/line-chart-consts';
2
+ import { setConfig } from './config';
3
+ import { getTranslations } from '../utils/translations/get-translations';
4
+ import { isPrimitiveValue } from '../utils/line-chart-utils';
5
+
6
+ /**
7
+ * Initialize the charts library with the provided configurations.
8
+ * This function will store the configuration options in a config object.
9
+ * @param {object} options - An object containing the configuration options for the library.
10
+ * @param {object} options.translations - The translations to be used in the library.
11
+ * @param {string} options.languageKey - The language key to be stored in the config object, used for translations.
12
+ * @param {...object} options - Any additional options to be stored in the config object.
13
+ */
14
+ export const initializeLineChart = ({ languageKey = 'en', ...options }) => {
15
+ setConfig(INIT_KEYS.LANGUAGE_KEY, languageKey);
16
+
17
+ Object.entries(options).forEach(([key, value]) => {
18
+ if (key === INIT_KEYS.TRANSLATIONS) {
19
+ setConfig(key, getTranslations(value));
20
+ } else {
21
+ const newValue = isPrimitiveValue(value) ? value : { ...value };
22
+ setConfig(key, newValue);
23
+ }
24
+ });
25
+ };
@@ -0,0 +1 @@
1
+ export const LEGEND_MARGIN = 4;
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import { useDrop } from 'react-dnd';
4
+ import styles from './legend.module.less';
5
+ import { Position } from '../../../helpers/enums';
6
+ import { LEGEND_MARGIN } from './legend-constants';
7
+
8
+ const LegendDropZone = ({ position, onDrop, placeholderSize }) => {
9
+ const [{ isOver, canDrop }, dropRef] = useDrop(() => ({
10
+ accept: 'legend',
11
+ drop: onDrop,
12
+ collect: (monitor) => ({
13
+ isOver: monitor.isOver(),
14
+ canDrop: monitor.canDrop(),
15
+ }),
16
+ }));
17
+ const isActive = isOver && canDrop;
18
+ return (
19
+ <div
20
+ ref={dropRef}
21
+ className={cx(
22
+ styles.dropzone,
23
+ isActive && styles.isActive,
24
+ position.includes('left') && styles.left,
25
+ position.includes('right') && styles.right,
26
+ position.includes('top') && styles.top,
27
+ position.includes('bottom') && styles.bottom,
28
+ )}
29
+ >
30
+ <div
31
+ className={styles.dropzonePlaceholder}
32
+ style={{ ...placeholderSize, margin: LEGEND_MARGIN }}
33
+ />
34
+ </div>
35
+ );
36
+ };
37
+
38
+ const LegendDropZones = ({
39
+ chartArea,
40
+ setLegendPosition,
41
+ isDragging,
42
+ placeholderSize,
43
+ }) => {
44
+ const positions = [
45
+ Position.TopLeft,
46
+ Position.TopRight,
47
+ Position.BottomLeft,
48
+ Position.BottomRight,
49
+ ];
50
+ const { top, left, width, height } = chartArea;
51
+ return (
52
+ <div
53
+ className={styles.dropzoneContainer}
54
+ style={{
55
+ top,
56
+ left,
57
+ width,
58
+ height,
59
+ zIndex: isDragging ? 0 : -1, // Position dropzones behind chart when not needed
60
+ }}
61
+ >
62
+ {positions.map((position) => (
63
+ <LegendDropZone
64
+ key={position}
65
+ position={position}
66
+ onDrop={() => setLegendPosition(position)}
67
+ placeholderSize={placeholderSize}
68
+ />
69
+ ))}
70
+ </div>
71
+ );
72
+ };
73
+
74
+ export default LegendDropZones;
@@ -0,0 +1,105 @@
1
+ import React from 'react';
2
+ import cx from 'classnames';
3
+ import { Icon } from '@oliasoft-open-source/react-ui-library';
4
+ import circleSvg from '../../../assets/circle.svg';
5
+ import rectSvg from '../../../assets/rect.svg';
6
+ import rectRotSvg from '../../../assets/rectRot.svg';
7
+ import triangleSvg from '../../../assets/triangle.svg';
8
+ import styles from './legend.module.less';
9
+ import { AnnotationType } from '../../../helpers/enums';
10
+
11
+ const LEGEND_SYMBOL_SIZE = 16;
12
+
13
+ const LegendItemLine = ({ dataset }) => {
14
+ const { borderColor, borderDash, borderWidth } = dataset;
15
+ // Center line dash on point
16
+ const offset = borderDash.length
17
+ ? (((LEGEND_SYMBOL_SIZE - borderDash[0]) / 2) %
18
+ (borderDash[0] + borderDash[1])) *
19
+ -1
20
+ : 0;
21
+
22
+ return (
23
+ <span className={styles.legendItemLine}>
24
+ <svg
25
+ xmlns="http://www.w3.org/2000/svg"
26
+ viewBox={`0 0 ${LEGEND_SYMBOL_SIZE} ${LEGEND_SYMBOL_SIZE}`}
27
+ >
28
+ <line
29
+ x1="0"
30
+ y1="50%"
31
+ x2="100%"
32
+ y2="50%"
33
+ stroke={borderColor}
34
+ strokeWidth={borderWidth}
35
+ strokeDasharray={borderDash}
36
+ strokeDashoffset={offset}
37
+ />
38
+ </svg>
39
+ </span>
40
+ );
41
+ };
42
+
43
+ const LegendItemPoint = ({ dataset }) => {
44
+ const { pointBackgroundColor, pointRadius, pointStyle } = dataset;
45
+ if (!pointRadius) return null;
46
+ const size = pointRadius * 2;
47
+ const icons = {
48
+ circle: circleSvg,
49
+ triangle: triangleSvg,
50
+ rectRot: rectRotSvg,
51
+ rect: rectSvg,
52
+ };
53
+ return (
54
+ <span className={styles.legendItemPoint}>
55
+ <Icon
56
+ icon={icons[pointStyle] || circleSvg}
57
+ size={size}
58
+ color={pointBackgroundColor}
59
+ />
60
+ </span>
61
+ );
62
+ };
63
+
64
+ const LegendItemBox = ({ dataset }) => {
65
+ const { backgroundColor } = dataset;
66
+ const style = { backgroundColor };
67
+ return <span className={styles.legendItemBox} style={style} />;
68
+ };
69
+
70
+ const LegendItemSymbol = ({ dataset }) => {
71
+ const { annotationType, showLine } = dataset;
72
+ switch (annotationType) {
73
+ case AnnotationType.Box:
74
+ case AnnotationType.Ellipse:
75
+ return <LegendItemBox dataset={dataset} />;
76
+ case AnnotationType.Line:
77
+ return <LegendItemLine dataset={dataset} />;
78
+ default:
79
+ return (
80
+ <>
81
+ {showLine && <LegendItemLine dataset={dataset} />}
82
+ <LegendItemPoint dataset={dataset} />
83
+ </>
84
+ );
85
+ }
86
+ };
87
+
88
+ const LegendItem = ({ hidden, dataset, handleClick }) => {
89
+ return (
90
+ <div
91
+ className={cx(styles.legendItem, hidden && styles.isHidden)}
92
+ onClick={handleClick}
93
+ >
94
+ <span
95
+ className={styles.legendItemSymbol}
96
+ style={{ width: LEGEND_SYMBOL_SIZE }}
97
+ >
98
+ <LegendItemSymbol dataset={dataset} />
99
+ </span>
100
+ <span className={styles.legendItemText}>{dataset.label}</span>
101
+ </div>
102
+ );
103
+ };
104
+
105
+ export default LegendItem;
@@ -0,0 +1,86 @@
1
+ import React, { forwardRef, useState } from 'react';
2
+ import cx from 'classnames';
3
+ import { Button } from '@oliasoft-open-source/react-ui-library';
4
+ import { TbList, TbX } from 'react-icons/tb';
5
+ import styles from './legend.module.less';
6
+ import { useToggleHandlers } from '../hooks/use-toggle-handler';
7
+ import { useChartFunctions } from '../hooks/use-chart-functions';
8
+ import LegendItem from './legend-item';
9
+ import { LEGEND_MARGIN } from './legend-constants';
10
+
11
+ const LegendPanel = forwardRef((props, ref) => {
12
+ const {
13
+ legendPosition,
14
+ chartRef,
15
+ state,
16
+ options,
17
+ dispatch,
18
+ generatedDatasets,
19
+ isDragging,
20
+ } = props;
21
+ const [refresh, setRefresh] = useState(false);
22
+ const { legendEnabled } = state;
23
+ const { legendClick } = useChartFunctions({
24
+ chartRef,
25
+ state,
26
+ options,
27
+ dispatch,
28
+ generatedDatasets,
29
+ });
30
+ const { onToggleLegend } = useToggleHandlers(dispatch);
31
+ const chart = chartRef.current;
32
+ if (!chart) return null;
33
+ const { data, chartArea, height = 0, width = 0 } = chart;
34
+ const { datasets } = data;
35
+ const { top, left, bottom, right } = chartArea;
36
+ const items =
37
+ chart.options?.plugins?.legend?.labels?.generateLabels(chart) ?? [];
38
+
39
+ const style = {
40
+ left: legendPosition.includes('left') ? left : null,
41
+ right: legendPosition.includes('right') ? width - right : null,
42
+ top: legendPosition.includes('top') ? top : null,
43
+ bottom: legendPosition.includes('bottom') ? height - bottom : null,
44
+ maxHeight: 0.5 * (bottom - top - LEGEND_MARGIN * 2),
45
+ maxWidth: 0.5 * (right - left - LEGEND_MARGIN * 2),
46
+ margin: LEGEND_MARGIN,
47
+ };
48
+
49
+ return (
50
+ <div
51
+ ref={ref}
52
+ className={cx(
53
+ styles.legend,
54
+ !legendEnabled && styles.isHidden,
55
+ isDragging && styles.isDragging,
56
+ )}
57
+ style={style}
58
+ >
59
+ <div className={styles.legendToggle}>
60
+ <Button
61
+ onClick={onToggleLegend}
62
+ small
63
+ round
64
+ icon={legendEnabled ? <TbX /> : <TbList />}
65
+ />
66
+ </div>
67
+ <div className={styles.legendItems}>
68
+ {items.map((item) => (
69
+ <LegendItem
70
+ key={`${item.datasetIndex}-hidden-${item.hidden}`}
71
+ hidden={item.hidden}
72
+ dataset={datasets[item.datasetIndex]}
73
+ handleClick={(event) => {
74
+ legendClick(event, item);
75
+ // TODO: Replace this hack with a better solution: item needs to rerender when "item.hidden" changes
76
+ // Force the legend item to update when clicked
77
+ setRefresh(!refresh);
78
+ }}
79
+ />
80
+ ))}
81
+ </div>
82
+ </div>
83
+ );
84
+ });
85
+
86
+ export default LegendPanel;
@@ -0,0 +1,54 @@
1
+ import React, { useRef, useState } from 'react';
2
+ import { useMeasure } from 'react-use';
3
+ import { useDrag } from 'react-dnd';
4
+ import LegendPanel from './legend-panel';
5
+ import LegendDropZones from './legend-dropzone';
6
+ import styles from './legend.module.less';
7
+
8
+ const Legend = ({ chartRef, state, options, dispatch, generatedDatasets }) => {
9
+ const [resizeRef] = useMeasure(); // Trigger update when chart is resized
10
+ const panelRef = useRef(null);
11
+ const chart = chartRef.current;
12
+ const [legendPosition, setLegendPosition] = useState(options.legend.position);
13
+ const panelRect = panelRef.current
14
+ ? panelRef.current.getBoundingClientRect()
15
+ : null;
16
+ const panelSize = { width: panelRect?.width, height: panelRect?.height };
17
+
18
+ const [{ isDragging }, dragRef] = useDrag(() => ({
19
+ type: 'legend',
20
+ collect: (monitor) => ({
21
+ isDragging: monitor.isDragging(),
22
+ }),
23
+ }));
24
+
25
+ if (!chart) return null;
26
+ const { chartArea } = chart;
27
+
28
+ return (
29
+ <>
30
+ <div ref={resizeRef} className={styles.resizeContainer} />
31
+ <LegendPanel
32
+ legendPosition={legendPosition}
33
+ chartRef={chartRef}
34
+ state={state}
35
+ options={options}
36
+ dispatch={dispatch}
37
+ generatedDatasets={generatedDatasets}
38
+ isDragging={isDragging}
39
+ ref={(r) => {
40
+ dragRef(r);
41
+ panelRef.current = r;
42
+ }}
43
+ />
44
+ <LegendDropZones
45
+ chartArea={chartArea}
46
+ setLegendPosition={setLegendPosition}
47
+ isDragging={isDragging}
48
+ placeholderSize={panelSize}
49
+ />
50
+ </>
51
+ );
52
+ };
53
+
54
+ export default Legend;
@@ -0,0 +1,192 @@
1
+ .legend {
2
+ position: absolute;
3
+ opacity: 0.9;
4
+ display: flex;
5
+ flex-direction: column;
6
+ z-index: 1;
7
+
8
+ &.isDragging {
9
+ opacity: 0;
10
+ }
11
+ }
12
+
13
+ .legendItems {
14
+ background-color: var(--color-background-raised);
15
+ border: 1px solid var(--color-border);
16
+ padding: 4px 8px;
17
+ border-radius: 2px;
18
+ overflow-y: auto;
19
+ max-height: 100%;
20
+ .scrollbars();
21
+
22
+ .legend.isDragging && {
23
+ pointer-events: none;
24
+ }
25
+
26
+ .legend.isHidden && {
27
+ display: none;
28
+ }
29
+ }
30
+
31
+ .legendToggle {
32
+ position: absolute;
33
+ top: 0;
34
+ right: 0;
35
+ transform: translate(50%, -50%);
36
+ display: none;
37
+
38
+ .legend.isHidden &&,
39
+ .legend:hover && {
40
+ display: block;
41
+ }
42
+
43
+ .legend:active && {
44
+ &:not(:hover) {
45
+ display: none;
46
+ }
47
+ }
48
+
49
+ .legend.isHidden && {
50
+ position: static;
51
+ transform: none;
52
+ }
53
+
54
+ .legend.isDragging && {
55
+ display: none;
56
+ }
57
+ }
58
+
59
+ .legendItem {
60
+ display: flex;
61
+ align-items: flex-start;
62
+ gap: 8px;
63
+ user-select: none;
64
+ cursor: pointer;
65
+ font-size: 12px;
66
+ line-height: 16px;
67
+ }
68
+
69
+ .legendItemSymbol {
70
+ display: flex;
71
+ align-items: center;
72
+ height: 16px;
73
+ position: relative;
74
+ flex-shrink: 0;
75
+
76
+ html[data-theme='dark'] && {
77
+ // Flip chart colors if dark mode enabled
78
+ filter: invert(1) hue-rotate(180deg);
79
+ }
80
+ }
81
+
82
+ .legendItemBox {
83
+ width: 100%;
84
+ height: 12px;
85
+ display: block;
86
+ }
87
+
88
+ .legendItemLine {
89
+ position: absolute;
90
+ display: flex;
91
+ top: 50%;
92
+ left: 0;
93
+ width: 100%;
94
+ transform: translateY(-50%);
95
+ }
96
+
97
+ .legendItemPoint {
98
+ position: absolute;
99
+ display: flex;
100
+ top: 50%;
101
+ left: 50%;
102
+ transform: translate(-50%, -50%);
103
+ }
104
+
105
+ .legendItemText {
106
+ .isHidden && {
107
+ text-decoration: line-through;
108
+ }
109
+ }
110
+
111
+ .scrollbars {
112
+ // https://dev.to/jonosellier/easy-overlay-scrollbars-variable-width-1mbh
113
+ overflow: overlay;
114
+ --scrollbar-color: #00000040;
115
+
116
+ &::-webkit-scrollbar {
117
+ display: block;
118
+ width: 16px;
119
+ z-index: 2;
120
+ }
121
+
122
+ &::-webkit-scrollbar-button {
123
+ display: none;
124
+ }
125
+
126
+ &::-webkit-scrollbar-track {
127
+ background-color: #00000000;
128
+ }
129
+
130
+ &::-webkit-scrollbar-track-piece {
131
+ background-color: #00000000;
132
+ }
133
+
134
+ &::-webkit-scrollbar-thumb {
135
+ background-color: #00000000;
136
+ border: 5px solid transparent;
137
+ border-radius: 24px;
138
+ box-shadow: 4px 0px 0px 4px var(--scrollbar-color) inset;
139
+ }
140
+
141
+ &::-webkit-scrollbar-corner {
142
+ background: rgba(0, 0, 0, 0);
143
+ }
144
+ }
145
+
146
+ .dropzoneContainer {
147
+ position: absolute;
148
+ }
149
+
150
+ .dropzone {
151
+ position: absolute;
152
+ width: 50%;
153
+ height: 50%;
154
+ display: flex;
155
+
156
+ &.left {
157
+ left: 0;
158
+ justify-content: flex-start;
159
+ }
160
+ &.right {
161
+ right: 0;
162
+ justify-content: flex-end;
163
+ }
164
+ &.top {
165
+ top: 0;
166
+ align-items: flex-start;
167
+ }
168
+ &.bottom {
169
+ bottom: 0;
170
+ align-items: flex-end;
171
+ }
172
+ }
173
+
174
+ .dropzonePlaceholder {
175
+ position: absolute;
176
+ background-color: rgba(black, 0.05);
177
+ display: none;
178
+
179
+ [data-theme='dark'] & {
180
+ background-color: rgba(white, 0.05);
181
+ }
182
+
183
+ .isActive && {
184
+ display: block;
185
+ }
186
+ }
187
+
188
+ .resizeContainer {
189
+ position: absolute;
190
+ inset: 0;
191
+ z-index: -1; // Display behind chart
192
+ }