@oliasoft-open-source/charts-library 2.14.0-beta-1 → 2.14.1-beta-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.
- package/package.json +1 -1
- package/release-notes.md +6 -0
- package/src/components/controls/axes-options/axes-options.jsx +5 -18
- package/src/components/line-chart/controls/axes-options/axes-options-form-state.js +8 -8
- package/src/components/line-chart/controls/controls.jsx +2 -7
- package/src/components/line-chart/controls/drag-options.jsx +6 -14
- package/src/components/line-chart/controls/legend-options.jsx +2 -6
- package/src/components/line-chart/controls/line-options.jsx +3 -4
- package/src/components/line-chart/line-chart.jsx +10 -7
- package/src/components/line-chart/state/use-chart-state.js +23 -9
- package/src/components/line-chart/utils/generate-line-chart-datasets.js +2 -8
- package/src/components/line-chart/constants/default-translations.js +0 -24
- package/src/components/line-chart/utils/get-translations/get-translations.js +0 -17
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oliasoft-open-source/charts-library",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.1-beta-1",
|
|
4
4
|
"description": "React Chart Library (based on Chart.js and react-chart-js-2)",
|
|
5
5
|
"homepage": "https://gitlab.com/oliasoft-open-source/charts-library",
|
|
6
6
|
"bugs": {
|
package/release-notes.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Charts Library Release Notes
|
|
2
2
|
|
|
3
|
+
## 2.14.1
|
|
4
|
+
- Fix save initAxesRange when dataset changed by subComponent
|
|
5
|
+
|
|
6
|
+
## 2.14.0
|
|
7
|
+
- Refactored line chart, for better performance, readable and reduce not needed re-renders
|
|
8
|
+
|
|
3
9
|
## 2.13.5
|
|
4
10
|
|
|
5
11
|
- Fixed reset range when subComponent update data, prevent extra re-renders when range have same deep values but different reference
|
|
@@ -31,7 +31,6 @@ const AxesOptionsPopover = ({
|
|
|
31
31
|
onResetAxes,
|
|
32
32
|
close,
|
|
33
33
|
depthType,
|
|
34
|
-
translations,
|
|
35
34
|
}) => {
|
|
36
35
|
const [depthTypeState, setDepthTypeState] = useState(
|
|
37
36
|
depthType?.selectedDepthType,
|
|
@@ -45,7 +44,7 @@ const AxesOptionsPopover = ({
|
|
|
45
44
|
initializeFormState,
|
|
46
45
|
);
|
|
47
46
|
|
|
48
|
-
const { errors, valid } = validateAxes(formState
|
|
47
|
+
const { errors, valid } = validateAxes(formState);
|
|
49
48
|
|
|
50
49
|
const onEditValue = ({ name, value, id }) => {
|
|
51
50
|
dispatch({
|
|
@@ -191,22 +190,16 @@ const AxesOptionsPopover = ({
|
|
|
191
190
|
) : null}
|
|
192
191
|
|
|
193
192
|
<Flex gap="8px" alignItems="center">
|
|
194
|
-
<Button
|
|
195
|
-
type="submit"
|
|
196
|
-
small
|
|
197
|
-
colored
|
|
198
|
-
label={translations.done}
|
|
199
|
-
disabled={!valid}
|
|
200
|
-
/>
|
|
193
|
+
<Button type="submit" small colored label="Done" disabled={!valid} />
|
|
201
194
|
<Button
|
|
202
195
|
small
|
|
203
196
|
name="resetAxes"
|
|
204
|
-
label=
|
|
197
|
+
label="Reset Axes"
|
|
205
198
|
onClick={onReset}
|
|
206
199
|
disabled={!isCustomValue}
|
|
207
200
|
/>
|
|
208
201
|
<Text small muted>
|
|
209
|
-
|
|
202
|
+
or double click on canvas
|
|
210
203
|
</Text>
|
|
211
204
|
</Flex>
|
|
212
205
|
</form>
|
|
@@ -220,7 +213,6 @@ export const AxesOptions = ({
|
|
|
220
213
|
onUpdateAxes,
|
|
221
214
|
onResetAxes,
|
|
222
215
|
depthType,
|
|
223
|
-
translations,
|
|
224
216
|
}) => {
|
|
225
217
|
return (
|
|
226
218
|
<Popover
|
|
@@ -234,15 +226,10 @@ export const AxesOptions = ({
|
|
|
234
226
|
onUpdateAxes={onUpdateAxes}
|
|
235
227
|
onResetAxes={onResetAxes}
|
|
236
228
|
depthType={depthType}
|
|
237
|
-
translations={translations}
|
|
238
229
|
/>
|
|
239
230
|
}
|
|
240
231
|
>
|
|
241
|
-
<Tooltip
|
|
242
|
-
text={translations.axesOptions}
|
|
243
|
-
placement="bottom"
|
|
244
|
-
display="flex"
|
|
245
|
-
>
|
|
232
|
+
<Tooltip text="Axes options" placement="bottom" display="flex">
|
|
246
233
|
<Button small basic colored="muted" round icon={<RiRuler2Line />} />
|
|
247
234
|
</Tooltip>
|
|
248
235
|
</Popover>
|
|
@@ -34,27 +34,27 @@ export const initializeFormState = ({ initialAxesRanges, axes = [] }) => {
|
|
|
34
34
|
|
|
35
35
|
const isEmptyString = (value) => value === '';
|
|
36
36
|
|
|
37
|
-
const createErrorMessages = (value, compareTo, type
|
|
37
|
+
const createErrorMessages = (value, compareTo, type) => {
|
|
38
38
|
const errors = [];
|
|
39
|
-
if (isEmptyString(value)) errors.push(
|
|
40
|
-
if (!validNumber(value)) errors.push(
|
|
39
|
+
if (isEmptyString(value)) errors.push('Must have a value');
|
|
40
|
+
if (!validNumber(value)) errors.push('Must be a number');
|
|
41
41
|
|
|
42
42
|
if (type === 'min' && !isLessThanMax(value, compareTo)) {
|
|
43
|
-
errors.push(
|
|
43
|
+
errors.push('Must be less than max');
|
|
44
44
|
} else if (type === 'max' && !isGreaterThanMin(value, compareTo)) {
|
|
45
|
-
errors.push(
|
|
45
|
+
errors.push('Must be greater than min');
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
return errors;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
export const validateAxes = (formState
|
|
51
|
+
export const validateAxes = (formState) => {
|
|
52
52
|
return formState.reduce(
|
|
53
53
|
(acc, { id, min, max }) => {
|
|
54
54
|
return produce(acc, (draft) => {
|
|
55
55
|
const errors = {
|
|
56
|
-
min: createErrorMessages(min, max, 'min'
|
|
57
|
-
max: createErrorMessages(max, min, 'max'
|
|
56
|
+
min: createErrorMessages(min, max, 'min'),
|
|
57
|
+
max: createErrorMessages(max, min, 'max'),
|
|
58
58
|
};
|
|
59
59
|
draft.errors.push({
|
|
60
60
|
id,
|
|
@@ -21,7 +21,6 @@ const Controls = ({
|
|
|
21
21
|
options,
|
|
22
22
|
dispatch,
|
|
23
23
|
generatedDatasets,
|
|
24
|
-
translations,
|
|
25
24
|
}) => {
|
|
26
25
|
const {
|
|
27
26
|
enableDragPoints,
|
|
@@ -73,21 +72,18 @@ const Controls = ({
|
|
|
73
72
|
onUpdateAxes={onUpdateAxes}
|
|
74
73
|
onResetAxes={onResetAxes}
|
|
75
74
|
depthType={options.depthType}
|
|
76
|
-
translations={translations}
|
|
77
75
|
/>
|
|
78
76
|
<LineOptions
|
|
79
77
|
lineEnabled={lineEnabled}
|
|
80
78
|
pointsEnabled={pointsEnabled}
|
|
81
79
|
onToggleLine={onToggleLine}
|
|
82
80
|
onTogglePoints={onTogglePoints}
|
|
83
|
-
translations={translations}
|
|
84
81
|
/>
|
|
85
82
|
<LegendOptions
|
|
86
83
|
legendEnabled={legendEnabled}
|
|
87
84
|
onToggleLegend={onToggleLegend}
|
|
88
|
-
translations={translations}
|
|
89
85
|
/>
|
|
90
|
-
<Tooltip text=
|
|
86
|
+
<Tooltip text="Download as PNG" placement="bottom-end">
|
|
91
87
|
<Button
|
|
92
88
|
small
|
|
93
89
|
basic
|
|
@@ -106,14 +102,13 @@ const Controls = ({
|
|
|
106
102
|
isDragDataAllowed={dragData.enableDragData}
|
|
107
103
|
onToggleDragPoints={onToggleDragPoints}
|
|
108
104
|
onDisableDragOptions={onDisableDragOptions}
|
|
109
|
-
translations={translations}
|
|
110
105
|
/>
|
|
111
106
|
</>
|
|
112
107
|
)}
|
|
113
108
|
|
|
114
109
|
{table ? (
|
|
115
110
|
<Tooltip
|
|
116
|
-
text={showTable ?
|
|
111
|
+
text={showTable ? 'Show chart' : 'Show table'}
|
|
117
112
|
placement="bottom-end"
|
|
118
113
|
>
|
|
119
114
|
<Button
|
|
@@ -13,24 +13,16 @@ export const DragOptions = ({
|
|
|
13
13
|
isDragDataAllowed,
|
|
14
14
|
onToggleDragPoints,
|
|
15
15
|
onDisableDragOptions,
|
|
16
|
-
translations: {
|
|
17
|
-
dragToZoom,
|
|
18
|
-
doubleClickToReset,
|
|
19
|
-
dragToPan,
|
|
20
|
-
orDoubleClickToCanvas,
|
|
21
|
-
dragToMovePoints,
|
|
22
|
-
dragDisabled,
|
|
23
|
-
},
|
|
24
16
|
}) => {
|
|
25
17
|
const options = useMemo(
|
|
26
18
|
() => [
|
|
27
19
|
{
|
|
28
|
-
buttonLabel:
|
|
20
|
+
buttonLabel: 'Drag to zoom',
|
|
29
21
|
label: (
|
|
30
22
|
<Flex direction="column">
|
|
31
23
|
<Text>Drag to zoom</Text>
|
|
32
24
|
<Text small muted>
|
|
33
|
-
|
|
25
|
+
Double click on canvas to reset
|
|
34
26
|
</Text>
|
|
35
27
|
</Flex>
|
|
36
28
|
),
|
|
@@ -39,12 +31,12 @@ export const DragOptions = ({
|
|
|
39
31
|
onClick: onToggleZoom,
|
|
40
32
|
},
|
|
41
33
|
{
|
|
42
|
-
buttonLabel:
|
|
34
|
+
buttonLabel: 'Drag to pan',
|
|
43
35
|
label: (
|
|
44
36
|
<Flex direction="column">
|
|
45
37
|
<Text>Drag to pan</Text>
|
|
46
38
|
<Text small muted>
|
|
47
|
-
|
|
39
|
+
Double click on canvas to reset
|
|
48
40
|
</Text>
|
|
49
41
|
</Flex>
|
|
50
42
|
),
|
|
@@ -55,7 +47,7 @@ export const DragOptions = ({
|
|
|
55
47
|
...(isDragDataAllowed
|
|
56
48
|
? [
|
|
57
49
|
{
|
|
58
|
-
label:
|
|
50
|
+
label: 'Drag to move points',
|
|
59
51
|
icon: <TbHandStop />,
|
|
60
52
|
selected: enableDragPoints,
|
|
61
53
|
type: 'Option',
|
|
@@ -64,7 +56,7 @@ export const DragOptions = ({
|
|
|
64
56
|
]
|
|
65
57
|
: []),
|
|
66
58
|
{
|
|
67
|
-
label:
|
|
59
|
+
label: 'Drag disabled',
|
|
68
60
|
icon: <RiForbidLine />,
|
|
69
61
|
selected: !zoomEnabled && !panEnabled && !enableDragPoints,
|
|
70
62
|
onClick: onDisableDragOptions,
|
|
@@ -4,12 +4,8 @@ import { Button, Icon, Tooltip } from '@oliasoft-open-source/react-ui-library';
|
|
|
4
4
|
import { RiListUnordered } from 'react-icons/ri';
|
|
5
5
|
import listHideIcon from '../../../assets/icons/list-hide.svg';
|
|
6
6
|
|
|
7
|
-
export const LegendOptions = ({
|
|
8
|
-
legendEnabled
|
|
9
|
-
onToggleLegend,
|
|
10
|
-
translations: { hideLegend, showLegend },
|
|
11
|
-
}) => {
|
|
12
|
-
const tooltipText = legendEnabled ? hideLegend : showLegend;
|
|
7
|
+
export const LegendOptions = ({ legendEnabled, onToggleLegend }) => {
|
|
8
|
+
const tooltipText = legendEnabled ? 'Hide Legend' : 'Show Legend';
|
|
13
9
|
const icon = legendEnabled ? (
|
|
14
10
|
<RiListUnordered />
|
|
15
11
|
) : (
|
|
@@ -10,11 +10,10 @@ export const LineOptions = ({
|
|
|
10
10
|
onToggleLine,
|
|
11
11
|
onTogglePoints,
|
|
12
12
|
pointsEnabled,
|
|
13
|
-
translations,
|
|
14
13
|
}) => {
|
|
15
14
|
const options = [
|
|
16
15
|
{
|
|
17
|
-
label:
|
|
16
|
+
label: 'Points & lines',
|
|
18
17
|
icon: <Icon icon={lineAndPointIcon} />,
|
|
19
18
|
selected: pointsEnabled && lineEnabled,
|
|
20
19
|
onClick: () => {
|
|
@@ -22,7 +21,7 @@ export const LineOptions = ({
|
|
|
22
21
|
},
|
|
23
22
|
},
|
|
24
23
|
{
|
|
25
|
-
label:
|
|
24
|
+
label: 'Lines only',
|
|
26
25
|
icon: <Icon icon={lineOnlyIcon} />,
|
|
27
26
|
selected: !pointsEnabled && lineEnabled,
|
|
28
27
|
onClick: () => {
|
|
@@ -31,7 +30,7 @@ export const LineOptions = ({
|
|
|
31
30
|
},
|
|
32
31
|
},
|
|
33
32
|
{
|
|
34
|
-
label:
|
|
33
|
+
label: 'Points only',
|
|
35
34
|
icon: <Icon icon={pointOnlyIcon} />,
|
|
36
35
|
selected: pointsEnabled && !lineEnabled,
|
|
37
36
|
onClick: () => {
|
|
@@ -29,8 +29,6 @@ import { useChartOptions } from './hooks/use-chart-options';
|
|
|
29
29
|
import { useChartPlugins } from './hooks/use-chart-plugins';
|
|
30
30
|
import { generateKey } from './utils/line-chart-utils';
|
|
31
31
|
import { useChartState } from './state/use-chart-state';
|
|
32
|
-
import { defaultTranslations } from './constants/default-translations';
|
|
33
|
-
import { getTranslations } from './utils/get-translations/get-translations';
|
|
34
32
|
|
|
35
33
|
ChartJS.register(
|
|
36
34
|
LinearScale,
|
|
@@ -55,8 +53,7 @@ ChartJS.register(
|
|
|
55
53
|
const LineChart = (props) => {
|
|
56
54
|
setDefaultTheme();
|
|
57
55
|
const chartRef = useRef(null);
|
|
58
|
-
const { table
|
|
59
|
-
const translations = getTranslations(translationsRaw);
|
|
56
|
+
const { table } = props;
|
|
60
57
|
const chart = getDefaultProps(props);
|
|
61
58
|
const {
|
|
62
59
|
data: { datasets },
|
|
@@ -79,11 +76,18 @@ const LineChart = (props) => {
|
|
|
79
76
|
);
|
|
80
77
|
|
|
81
78
|
const generatedDatasets = useMemo(() => {
|
|
82
|
-
return generateLineChartDatasets(datasets, state, options
|
|
79
|
+
return generateLineChartDatasets(datasets, state, options);
|
|
83
80
|
}, [state.lineEnabled, state.pointsEnabled, axes, annotations, graph]);
|
|
84
81
|
|
|
85
82
|
// Call the custom hooks.
|
|
86
|
-
useChartState({
|
|
83
|
+
useChartState({
|
|
84
|
+
chartRef,
|
|
85
|
+
options,
|
|
86
|
+
state,
|
|
87
|
+
generatedDatasets,
|
|
88
|
+
dispatch,
|
|
89
|
+
persistenceId,
|
|
90
|
+
});
|
|
87
91
|
|
|
88
92
|
const { resetZoom, handleDownload, handleKeyDown, handleKeyUp } =
|
|
89
93
|
useChartFunctions({
|
|
@@ -128,7 +132,6 @@ const LineChart = (props) => {
|
|
|
128
132
|
options={options}
|
|
129
133
|
dispatch={dispatch}
|
|
130
134
|
generatedDatasets={generatedDatasets}
|
|
131
|
-
translations={translations}
|
|
132
135
|
/>
|
|
133
136
|
{table && state.showTable ? (
|
|
134
137
|
<div className={styles.table}>{table}</div>
|
|
@@ -75,26 +75,38 @@ const useUpdateAxesRanges = (range, dispatch) => {
|
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
78
|
+
* A custom hook to save the initial axes ranges of a chart when the generated datasets change.
|
|
79
79
|
*
|
|
80
|
-
* @param chartRef -
|
|
81
|
-
* @param axes -
|
|
82
|
-
* @param
|
|
80
|
+
* @param {Object} chartRef - A reference to the chart object.
|
|
81
|
+
* @param {Array} axes - An array of axes configurations.
|
|
82
|
+
* @param {Array} generatedDatasets - An array of generated datasets for the chart.
|
|
83
|
+
* @param {Function} dispatch - A dispatch function from the useContext hook for managing the state.
|
|
83
84
|
*/
|
|
84
|
-
const useSaveInitialAxesRanges = (
|
|
85
|
+
const useSaveInitialAxesRanges = (
|
|
86
|
+
chartRef,
|
|
87
|
+
axes,
|
|
88
|
+
generatedDatasets,
|
|
89
|
+
dispatch,
|
|
90
|
+
) => {
|
|
91
|
+
const prevGeneratedDatasets = useRef();
|
|
92
|
+
|
|
85
93
|
const saveInitialAxesRanges = useCallback(() => {
|
|
86
|
-
if (
|
|
94
|
+
if (
|
|
95
|
+
chartRef &&
|
|
96
|
+
!isEqual(generatedDatasets, prevGeneratedDatasets.current)
|
|
97
|
+
) {
|
|
87
98
|
const initialAxesRanges = getAxesRangesFromChart(chartRef, axes);
|
|
88
99
|
dispatch({
|
|
89
100
|
type: SAVE_INITIAL_AXES_RANGES,
|
|
90
101
|
payload: { initialAxesRanges },
|
|
91
102
|
});
|
|
103
|
+
prevGeneratedDatasets.current = generatedDatasets;
|
|
92
104
|
}
|
|
93
|
-
}, [chartRef]);
|
|
105
|
+
}, [chartRef, generatedDatasets]);
|
|
94
106
|
|
|
95
107
|
useEffect(() => {
|
|
96
108
|
saveInitialAxesRanges();
|
|
97
|
-
}, [saveInitialAxesRanges]);
|
|
109
|
+
}, [saveInitialAxesRanges, generatedDatasets]);
|
|
98
110
|
};
|
|
99
111
|
|
|
100
112
|
/**
|
|
@@ -103,6 +115,7 @@ const useSaveInitialAxesRanges = (chartRef, axes, dispatch) => {
|
|
|
103
115
|
* @param chartRef - The reference to the chart.
|
|
104
116
|
* @param options - The chart options.
|
|
105
117
|
* @param state - The chart state.
|
|
118
|
+
* @param {Array} generatedDatasets - An array of generated datasets for the chart.
|
|
106
119
|
* @param dispatch - The dispatch function for state management.
|
|
107
120
|
* @param persistenceId - The chart persistenceId.
|
|
108
121
|
*/
|
|
@@ -110,6 +123,7 @@ export const useChartState = ({
|
|
|
110
123
|
chartRef,
|
|
111
124
|
options,
|
|
112
125
|
state,
|
|
126
|
+
generatedDatasets,
|
|
113
127
|
dispatch,
|
|
114
128
|
persistenceId,
|
|
115
129
|
}) => {
|
|
@@ -123,5 +137,5 @@ export const useChartState = ({
|
|
|
123
137
|
useStoreChartStateInStorage(memoState, persistenceId);
|
|
124
138
|
useToggleCustomLegendVisibility(memoState, memoOptions);
|
|
125
139
|
useUpdateAxesRanges(range, dispatch);
|
|
126
|
-
useSaveInitialAxesRanges(chartRef, axes, dispatch);
|
|
140
|
+
useSaveInitialAxesRanges(chartRef, axes, generatedDatasets, dispatch);
|
|
127
141
|
};
|
|
@@ -15,15 +15,9 @@ import { generateRandomColor } from '../../../helpers/chart-utils';
|
|
|
15
15
|
* @param {Array} datasets - The initial datasets for the line chart.
|
|
16
16
|
* @param {Object} state - The state object containing chart settings (e.g., lineEnabled, pointsEnabled, axes).
|
|
17
17
|
* @param {Object} options - The options object containing additional settings (e.g., annotations, graph).
|
|
18
|
-
* @param {Object} translations - The translations object containing translations string
|
|
19
18
|
* @returns {Array} - The generated line chart datasets with applied settings and configurations.
|
|
20
19
|
*/
|
|
21
|
-
export const generateLineChartDatasets = (
|
|
22
|
-
datasets,
|
|
23
|
-
state,
|
|
24
|
-
options,
|
|
25
|
-
translations,
|
|
26
|
-
) => {
|
|
20
|
+
export const generateLineChartDatasets = (datasets, state, options) => {
|
|
27
21
|
const copyDataset = [...datasets];
|
|
28
22
|
const { annotations, graph } = options;
|
|
29
23
|
const {
|
|
@@ -94,7 +88,7 @@ export const generateLineChartDatasets = (
|
|
|
94
88
|
// Return the dataset with applied settings and configurations
|
|
95
89
|
return {
|
|
96
90
|
...line,
|
|
97
|
-
label: line.label ||
|
|
91
|
+
label: line.label || `Label ${i + 1}`,
|
|
98
92
|
data: filteredData,
|
|
99
93
|
showLine: lineEnabled,
|
|
100
94
|
lineTension,
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export const defaultTranslations = Object.freeze({
|
|
2
|
-
label: 'Label',
|
|
3
|
-
pointsLines: 'Points & lines',
|
|
4
|
-
linesOnly: 'Lines only',
|
|
5
|
-
pointsOnly: 'Points only',
|
|
6
|
-
axesOptions: 'Axes options',
|
|
7
|
-
resetAxes: 'Reset Axes',
|
|
8
|
-
done: 'Done',
|
|
9
|
-
downloadAsPNG: 'Download as PNG',
|
|
10
|
-
showChart: 'Show chart',
|
|
11
|
-
showTable: 'Show table',
|
|
12
|
-
dragToZoom: 'Drag to zoom',
|
|
13
|
-
dragToPan: 'Drag to pan',
|
|
14
|
-
dragToMovePoints: 'Drag to move points',
|
|
15
|
-
dragDisabled: 'Drag disabled',
|
|
16
|
-
hideLegend: 'Hide Legend',
|
|
17
|
-
showLegend: 'Show Legend',
|
|
18
|
-
mustHaveAValue: 'Must have a value',
|
|
19
|
-
mustBeANumber: 'Must be a number',
|
|
20
|
-
mustBeLessThanMax: 'Must be less than max',
|
|
21
|
-
mustBeGreaterThanMin: 'Must be greater than min',
|
|
22
|
-
doubleClickToReset: 'Double click on canvas to reset',
|
|
23
|
-
orDoubleClickToCanvas: 'or double click on canvas',
|
|
24
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { defaultTranslations } from '../../constants/default-translations';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Merges custom translations with the default translations.
|
|
5
|
-
* If a custom translation is provided for a key, it will override the default one.
|
|
6
|
-
* @param {object} translations - Custom translations.
|
|
7
|
-
* @returns {object} - The resulting translations object, containing both default and custom translations.
|
|
8
|
-
*/
|
|
9
|
-
export const getTranslations = (translations = {}) => {
|
|
10
|
-
return Object.keys(defaultTranslations).reduce(
|
|
11
|
-
(acc, key) => ({
|
|
12
|
-
...acc,
|
|
13
|
-
[key]: translations[key] || defaultTranslations[key],
|
|
14
|
-
}),
|
|
15
|
-
{},
|
|
16
|
-
);
|
|
17
|
-
};
|