diff --git a/config/jestsetup.ts b/config/jestsetup.ts
index af42e14d863..809d31efd5c 100644
--- a/config/jestsetup.ts
+++ b/config/jestsetup.ts
@@ -2,6 +2,7 @@ import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { createSerializer } from 'enzyme-to-json';
import jssSerializer from '@shared/tests/serializer/jss-snapshot-serializer';
+import contentLoaderSerializer from '@shared/tests/serializer/content-loader-serializer.js';
process.env.NODE_ENV = 'test';
process.env.BABEL_ENV = 'test';
@@ -22,6 +23,7 @@ expect.addSnapshotSerializer(
})
);
expect.addSnapshotSerializer(jssSerializer);
+expect.addSnapshotSerializer(contentLoaderSerializer);
export const setupMatchMedia = () => {
// @ts-ignore
diff --git a/packages/charts/src/components/BarChart/BarChart.test.tsx b/packages/charts/src/components/BarChart/BarChart.test.tsx
index 47b6b93cd78..852ef87b639 100644
--- a/packages/charts/src/components/BarChart/BarChart.test.tsx
+++ b/packages/charts/src/components/BarChart/BarChart.test.tsx
@@ -5,15 +5,15 @@ import { BarChart } from './index';
describe('BarChart', () => {
test('Renders with data', () => {
- renderThemedComponent();
+ mountThemedComponent();
});
test('custom colors', () => {
- renderThemedComponent();
+ mountThemedComponent();
});
test('valueAxisFormatter', () => {
- renderThemedComponent( `${d}%`} />);
+ mountThemedComponent( `${d}%`} />);
});
test('with Ref', () => {
@@ -23,7 +23,7 @@ describe('BarChart', () => {
});
test('stacked', () => {
- renderThemedComponent(
+ mountThemedComponent(
{
/>
);
});
+
+ test('loading placeholder', () => {
+ const wrapper = mountThemedComponent();
+ expect(wrapper.render()).toMatchSnapshot();
+ });
});
diff --git a/packages/charts/src/components/BarChart/Placeholder.tsx b/packages/charts/src/components/BarChart/Placeholder.tsx
index 4cbfef29f8b..84f7ea321f9 100644
--- a/packages/charts/src/components/BarChart/Placeholder.tsx
+++ b/packages/charts/src/components/BarChart/Placeholder.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import ContentLoader from 'react-content-loader';
-export const BarChartPlaceholder = (props) => {
+export const BarChartPlaceholder = () => {
return (
{
primaryColor="#6a6d70"
secondaryColor="#d9d9d9"
primaryOpacity={0.3}
- {...props}
>
diff --git a/packages/charts/src/components/BarChart/__snapshots__/BarChart.test.tsx.snap b/packages/charts/src/components/BarChart/__snapshots__/BarChart.test.tsx.snap
new file mode 100644
index 00000000000..314419fdb56
--- /dev/null
+++ b/packages/charts/src/components/BarChart/__snapshots__/BarChart.test.tsx.snap
@@ -0,0 +1,118 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`BarChart loading placeholder 1`] = `
+
+
+
+`;
diff --git a/packages/charts/src/components/BarChart/demo.stories.tsx b/packages/charts/src/components/BarChart/demo.stories.tsx
index 3ced6ccab6a..b8db4e96ad9 100644
--- a/packages/charts/src/components/BarChart/demo.stories.tsx
+++ b/packages/charts/src/components/BarChart/demo.stories.tsx
@@ -53,4 +53,5 @@ storiesOf('Charts | BarChart', module)
options={options}
loading={boolean('loading')}
/>
- ));
+ ))
+ .add('Loading Placeholder', () => );
diff --git a/packages/charts/src/components/BarChart/index.tsx b/packages/charts/src/components/BarChart/index.tsx
index 6e2584a1cba..63786742fe5 100644
--- a/packages/charts/src/components/BarChart/index.tsx
+++ b/packages/charts/src/components/BarChart/index.tsx
@@ -13,125 +13,124 @@ import { BarChartPlaceholder } from './Placeholder';
export interface BarChartPropTypes extends ChartBaseProps {}
-const BarChart = withChartContainer(
- forwardRef((props: BarChartPropTypes, ref: Ref) => {
- const {
- labels,
- datasets,
- options,
- categoryAxisFormatter,
- valueAxisFormatter,
- getDatasetAtEvent,
- getElementAtEvent,
- colors,
- width,
- height,
- noLegend
- } = props as BarChartPropTypes;
+const BarChartComponent = forwardRef((props: BarChartPropTypes, ref: Ref) => {
+ const {
+ labels,
+ datasets,
+ options,
+ categoryAxisFormatter,
+ valueAxisFormatter,
+ getDatasetAtEvent,
+ getElementAtEvent,
+ colors,
+ width,
+ height,
+ noLegend
+ } = props as BarChartPropTypes;
- const theme: any = useTheme();
- const data = useChartData(labels, datasets, colors, theme.theme);
+ const theme: any = useTheme();
+ const data = useChartData(labels, datasets, colors, theme.theme);
- const chartRef = useConsolidatedRef(ref);
- const legendRef: RefObject = useRef();
+ const chartRef = useConsolidatedRef(ref);
+ const legendRef: RefObject = useRef();
- const handleLegendItemPress = useCallback(
- (e) => {
- const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
- const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
- const { chartInstance } = chartRef.current;
- const meta = chartInstance.getDatasetMeta(datasetIndex);
- meta.hidden = meta.hidden === null ? !chartInstance.data.datasets[datasetIndex].hidden : null;
- chartInstance.update();
- clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
- },
- [legendRef.current, chartRef.current]
- );
+ const handleLegendItemPress = useCallback(
+ (e) => {
+ const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
+ const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
+ const { chartInstance } = chartRef.current;
+ const meta = chartInstance.getDatasetMeta(datasetIndex);
+ meta.hidden = meta.hidden === null ? !chartInstance.data.datasets[datasetIndex].hidden : null;
+ chartInstance.update();
+ clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
+ },
+ [legendRef.current, chartRef.current]
+ );
- useEffect(() => {
- if (noLegend) {
- legendRef.current.innerHTML = '';
- } else {
- legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
- legendRef.current.querySelectorAll('li').forEach((legendItem) => {
- legendItem.addEventListener('click', handleLegendItemPress);
- });
- }
- }, [chartRef.current, legendRef.current, noLegend]);
+ useEffect(() => {
+ if (noLegend) {
+ legendRef.current.innerHTML = '';
+ } else {
+ legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
+ legendRef.current.querySelectorAll('li').forEach((legendItem) => {
+ legendItem.addEventListener('click', handleLegendItemPress);
+ });
+ }
+ }, [chartRef.current, legendRef.current, noLegend]);
- const barChartDefaultConfig = useMemo(() => {
- return {
- scales: {
- xAxes: [
- {
- ...DEFAULT_OPTIONS.scales.yAxes[0],
- ticks: {
- callback: valueAxisFormatter
- }
- }
- ],
- yAxes: [
- {
- ...DEFAULT_OPTIONS.scales.xAxes[0],
- ticks: {
- callback: categoryAxisFormatter
- }
+ const barChartDefaultConfig = useMemo(() => {
+ return {
+ scales: {
+ xAxes: [
+ {
+ ...DEFAULT_OPTIONS.scales.yAxes[0],
+ ticks: {
+ callback: valueAxisFormatter
}
- ]
- },
- tooltips: {
- callbacks: {
- label: formatTooltipLabel(categoryAxisFormatter, valueAxisFormatter, 'xLabel')
}
- },
- plugins: {
- datalabels: {
- anchor: 'end',
- align: 'start',
- clip: true,
- display: (context) => {
- const datasetMeta = context.chart.getDatasetMeta(context.datasetIndex);
- const dataMeta = datasetMeta.data[context.dataIndex];
- const width = dataMeta._view.x - dataMeta._view.base;
- const formattedValue = valueAxisFormatter(context.dataset.data[context.dataIndex]);
- const textWidth = getTextWidth(formattedValue) + 4; // offset
- return width >= textWidth;
- },
- formatter: valueAxisFormatter,
- color: (context) => {
- const datasetMeta = context.chart.getDatasetMeta(context.datasetIndex);
- const dataMeta = datasetMeta.data[context.dataIndex];
- return bestContrast(dataMeta._view.backgroundColor, [
- /* sapUiBaseText */ '#32363a',
- /* sapUiContentContrastTextColor */ '#ffffff'
- ]);
+ ],
+ yAxes: [
+ {
+ ...DEFAULT_OPTIONS.scales.xAxes[0],
+ ticks: {
+ callback: categoryAxisFormatter
}
}
+ ]
+ },
+ tooltips: {
+ callbacks: {
+ label: formatTooltipLabel(categoryAxisFormatter, valueAxisFormatter, 'xLabel')
}
- };
- }, [valueAxisFormatter, categoryAxisFormatter]);
-
- const mergedOptions = useMergedConfig(barChartDefaultConfig, options);
+ },
+ plugins: {
+ datalabels: {
+ anchor: 'end',
+ align: 'start',
+ clip: true,
+ display: (context) => {
+ const datasetMeta = context.chart.getDatasetMeta(context.datasetIndex);
+ const dataMeta = datasetMeta.data[context.dataIndex];
+ const width = dataMeta._view.x - dataMeta._view.base;
+ const formattedValue = valueAxisFormatter(context.dataset.data[context.dataIndex]);
+ const textWidth = getTextWidth(formattedValue) + 4; // offset
+ return width >= textWidth;
+ },
+ formatter: valueAxisFormatter,
+ color: (context) => {
+ const datasetMeta = context.chart.getDatasetMeta(context.datasetIndex);
+ const dataMeta = datasetMeta.data[context.dataIndex];
+ return bestContrast(dataMeta._view.backgroundColor, [
+ /* sapUiBaseText */ '#32363a',
+ /* sapUiContentContrastTextColor */ '#ffffff'
+ ]);
+ }
+ }
+ }
+ };
+ }, [valueAxisFormatter, categoryAxisFormatter]);
- return (
- <>
-
-
- >
- );
- })
-);
+ const mergedOptions = useMergedConfig(barChartDefaultConfig, options);
+ return (
+ <>
+
+
+ >
+ );
+});
// @ts-ignore
-BarChart.LoadingPlaceholder = BarChartPlaceholder;
+BarChartComponent.LoadingPlaceholder = BarChartPlaceholder;
+const BarChart = withChartContainer(BarChartComponent);
+
BarChart.defaultProps = {
...ChartBaseDefaultProps
};
diff --git a/packages/charts/src/components/ColumnChart/ColumnChart.test.tsx b/packages/charts/src/components/ColumnChart/ColumnChart.test.tsx
index 021635c7f1e..d6ea738e32c 100644
--- a/packages/charts/src/components/ColumnChart/ColumnChart.test.tsx
+++ b/packages/charts/src/components/ColumnChart/ColumnChart.test.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { renderThemedComponent } from '@shared/tests/utils';
+import { mountThemedComponent, renderThemedComponent } from '@shared/tests/utils';
import { ColumnChart } from './index';
import { labels, singleDataset } from '../../test/resources/ChartProps';
@@ -7,4 +7,9 @@ describe('ColumnChart', () => {
test('Renders with data', () => {
renderThemedComponent();
});
+
+ test('loading placeholder', () => {
+ const wrapper = mountThemedComponent();
+ expect(wrapper.render()).toMatchSnapshot();
+ });
});
diff --git a/packages/charts/src/components/ColumnChart/__snapshots__/ColumnChart.test.tsx.snap b/packages/charts/src/components/ColumnChart/__snapshots__/ColumnChart.test.tsx.snap
new file mode 100644
index 00000000000..dcc4b8607b2
--- /dev/null
+++ b/packages/charts/src/components/ColumnChart/__snapshots__/ColumnChart.test.tsx.snap
@@ -0,0 +1,118 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ColumnChart loading placeholder 1`] = `
+
+
+
+`;
diff --git a/packages/charts/src/components/ColumnChart/demo.stories.tsx b/packages/charts/src/components/ColumnChart/demo.stories.tsx
index ada972065d1..e6fb82ca051 100644
--- a/packages/charts/src/components/ColumnChart/demo.stories.tsx
+++ b/packages/charts/src/components/ColumnChart/demo.stories.tsx
@@ -99,4 +99,5 @@ storiesOf('Charts | ColumnChart', module)
options={growthLineOptions}
loading={boolean('loading')}
/>
- ));
+ ))
+ .add('Loading Placeholder', () => );
diff --git a/packages/charts/src/components/ColumnChart/index.tsx b/packages/charts/src/components/ColumnChart/index.tsx
index 08ce89e130b..040eea787d8 100644
--- a/packages/charts/src/components/ColumnChart/index.tsx
+++ b/packages/charts/src/components/ColumnChart/index.tsx
@@ -13,128 +13,127 @@ import { ColumnChartPlaceholder } from './Placeholder';
export interface ColumnChartPropTypes extends ChartBaseProps {}
-const ColumnChart = withChartContainer(
- forwardRef((props: ColumnChartPropTypes, ref: Ref) => {
- const {
- labels,
- datasets,
- categoryAxisFormatter,
- valueAxisFormatter,
- getDatasetAtEvent,
- getElementAtEvent,
- colors,
- options,
- width,
- height,
- noLegend
- } = props;
+const ColumnChartComponent = forwardRef((props: ColumnChartPropTypes, ref: Ref) => {
+ const {
+ labels,
+ datasets,
+ categoryAxisFormatter,
+ valueAxisFormatter,
+ getDatasetAtEvent,
+ getElementAtEvent,
+ colors,
+ options,
+ width,
+ height,
+ noLegend
+ } = props;
- const theme: any = useTheme();
- const data = useChartData(labels, datasets, colors, theme.theme);
+ const theme: any = useTheme();
+ const data = useChartData(labels, datasets, colors, theme.theme);
- const chartRef = useConsolidatedRef(ref);
- const legendRef: RefObject = useRef();
+ const chartRef = useConsolidatedRef(ref);
+ const legendRef: RefObject = useRef();
- const handleLegendItemPress = useCallback(
- (e) => {
- const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
- const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
- const { chartInstance } = chartRef.current;
- const meta = chartInstance.getDatasetMeta(datasetIndex);
- meta.hidden = meta.hidden === null ? !chartInstance.data.datasets[datasetIndex].hidden : null;
- chartInstance.update();
- clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
- },
- [legendRef.current, chartRef.current]
- );
+ const handleLegendItemPress = useCallback(
+ (e) => {
+ const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
+ const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
+ const { chartInstance } = chartRef.current;
+ const meta = chartInstance.getDatasetMeta(datasetIndex);
+ meta.hidden = meta.hidden === null ? !chartInstance.data.datasets[datasetIndex].hidden : null;
+ chartInstance.update();
+ clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
+ },
+ [legendRef.current, chartRef.current]
+ );
- useEffect(() => {
- if (noLegend) {
- legendRef.current.innerHTML = '';
- } else {
- legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
- legendRef.current.querySelectorAll('li').forEach((legendItem) => {
- legendItem.addEventListener('click', handleLegendItemPress);
- });
- }
- }, [chartRef.current, legendRef.current, noLegend]);
+ useEffect(() => {
+ if (noLegend) {
+ legendRef.current.innerHTML = '';
+ } else {
+ legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
+ legendRef.current.querySelectorAll('li').forEach((legendItem) => {
+ legendItem.addEventListener('click', handleLegendItemPress);
+ });
+ }
+ }, [chartRef.current, legendRef.current, noLegend]);
- const columnChartDefaultConfig = useMemo(() => {
- return {
- scales: {
- xAxes: [
- {
- ...DEFAULT_OPTIONS.scales.xAxes[0],
- ticks: {
- callback: categoryAxisFormatter
- }
+ const columnChartDefaultConfig = useMemo(() => {
+ return {
+ scales: {
+ xAxes: [
+ {
+ ...DEFAULT_OPTIONS.scales.xAxes[0],
+ ticks: {
+ callback: categoryAxisFormatter
}
- ],
- yAxes: [
- {
- ...DEFAULT_OPTIONS.scales.yAxes[0],
- ticks: {
- ...DEFAULT_OPTIONS.scales.yAxes[0].ticks,
- callback: valueAxisFormatter
- }
+ }
+ ],
+ yAxes: [
+ {
+ ...DEFAULT_OPTIONS.scales.yAxes[0],
+ ticks: {
+ ...DEFAULT_OPTIONS.scales.yAxes[0].ticks,
+ callback: valueAxisFormatter
}
- ]
- },
- tooltips: {
- callbacks: {
- label: formatTooltipLabel(categoryAxisFormatter, valueAxisFormatter)
}
- },
- plugins: {
- datalabels: {
- display: (context) => {
- const datasetMeta = context.chart.getDatasetMeta(context.datasetIndex);
- const dataMeta = datasetMeta.data[context.dataIndex];
- const height = dataMeta._view.base - dataMeta._view.y; // offset
- if (height < getTextHeight() + 6) {
- return false;
- }
- const formattedValue = valueAxisFormatter(context.dataset.data[context.dataIndex]);
- const textWidth = getTextWidth(formattedValue);
- return textWidth < dataMeta._view.width;
- },
- anchor: 'end',
- align: 'start',
- formatter: valueAxisFormatter,
- color: (context) => {
- const datasetMeta = context.chart.getDatasetMeta(context.datasetIndex);
- const dataMeta = datasetMeta.data[context.dataIndex];
- return bestContrast(dataMeta._view.backgroundColor, [
- /* sapUiBaseText */ '#32363a',
- /* sapUiContentContrastTextColor */ '#ffffff'
- ]);
+ ]
+ },
+ tooltips: {
+ callbacks: {
+ label: formatTooltipLabel(categoryAxisFormatter, valueAxisFormatter)
+ }
+ },
+ plugins: {
+ datalabels: {
+ display: (context) => {
+ const datasetMeta = context.chart.getDatasetMeta(context.datasetIndex);
+ const dataMeta = datasetMeta.data[context.dataIndex];
+ const height = dataMeta._view.base - dataMeta._view.y; // offset
+ if (height < getTextHeight() + 6) {
+ return false;
}
+ const formattedValue = valueAxisFormatter(context.dataset.data[context.dataIndex]);
+ const textWidth = getTextWidth(formattedValue);
+ return textWidth < dataMeta._view.width;
+ },
+ anchor: 'end',
+ align: 'start',
+ formatter: valueAxisFormatter,
+ color: (context) => {
+ const datasetMeta = context.chart.getDatasetMeta(context.datasetIndex);
+ const dataMeta = datasetMeta.data[context.dataIndex];
+ return bestContrast(dataMeta._view.backgroundColor, [
+ /* sapUiBaseText */ '#32363a',
+ /* sapUiContentContrastTextColor */ '#ffffff'
+ ]);
}
}
- };
- }, [categoryAxisFormatter, valueAxisFormatter]);
-
- const mergedOptions = useMergedConfig(columnChartDefaultConfig, options);
+ }
+ };
+ }, [categoryAxisFormatter, valueAxisFormatter]);
- return (
- <>
-
-
- >
- );
- })
-);
+ const mergedOptions = useMergedConfig(columnChartDefaultConfig, options);
+ return (
+ <>
+
+
+ >
+ );
+});
// @ts-ignore
-ColumnChart.LoadingPlaceholder = ColumnChartPlaceholder;
+ColumnChartComponent.LoadingPlaceholder = ColumnChartPlaceholder;
+const ColumnChart = withChartContainer(ColumnChartComponent);
+
ColumnChart.defaultProps = {
...ChartBaseDefaultProps
};
diff --git a/packages/charts/src/components/DonutChart/DonutChart.test.tsx b/packages/charts/src/components/DonutChart/DonutChart.test.tsx
index ab6803ba0e4..cb0f72c6ecc 100644
--- a/packages/charts/src/components/DonutChart/DonutChart.test.tsx
+++ b/packages/charts/src/components/DonutChart/DonutChart.test.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { renderThemedComponent } from '@shared/tests/utils';
+import { mountThemedComponent, renderThemedComponent } from '@shared/tests/utils';
import { DonutChart } from './index';
import { labels, singleDataset } from '../../test/resources/ChartProps';
@@ -7,4 +7,9 @@ describe('DonutChart', () => {
test('Renders with data', () => {
renderThemedComponent();
});
+
+ test('loading placeholder', () => {
+ const wrapper = mountThemedComponent();
+ expect(wrapper.render()).toMatchSnapshot();
+ });
});
diff --git a/packages/charts/src/components/DonutChart/__snapshots__/DonutChart.test.tsx.snap b/packages/charts/src/components/DonutChart/__snapshots__/DonutChart.test.tsx.snap
new file mode 100644
index 00000000000..e572723caa2
--- /dev/null
+++ b/packages/charts/src/components/DonutChart/__snapshots__/DonutChart.test.tsx.snap
@@ -0,0 +1,81 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DonutChart loading placeholder 1`] = `
+
+
+
+`;
diff --git a/packages/charts/src/components/DonutChart/demo.stories.tsx b/packages/charts/src/components/DonutChart/demo.stories.tsx
index 38d9372461a..5ca413fde66 100644
--- a/packages/charts/src/components/DonutChart/demo.stories.tsx
+++ b/packages/charts/src/components/DonutChart/demo.stories.tsx
@@ -27,4 +27,5 @@ storiesOf('Charts | DonutChart', module)
valueAxisFormatter={(number) => `${number}$`}
loading={boolean('loading')}
/>
- ));
+ ))
+ .add('Loading Placeholder', () => );
diff --git a/packages/charts/src/components/DonutChart/index.tsx b/packages/charts/src/components/DonutChart/index.tsx
index 1e798465cee..65e7c4a462c 100644
--- a/packages/charts/src/components/DonutChart/index.tsx
+++ b/packages/charts/src/components/DonutChart/index.tsx
@@ -11,94 +11,94 @@ import { PieChartPlaceholder } from '../PieChart/Placeholder';
export interface DonutChartPropTypes extends ChartBaseProps {}
-const DonutChart = withChartContainer(
- forwardRef((props: DonutChartPropTypes, ref: Ref) => {
- const {
- labels,
- datasets,
- colors,
- categoryAxisFormatter,
- getDatasetAtEvent,
- getElementAtEvent,
- valueAxisFormatter,
- options,
- width,
- height,
- noLegend
- } = props;
+const DonutChartComponent = forwardRef((props: DonutChartPropTypes, ref: Ref) => {
+ const {
+ labels,
+ datasets,
+ colors,
+ categoryAxisFormatter,
+ getDatasetAtEvent,
+ getElementAtEvent,
+ valueAxisFormatter,
+ options,
+ width,
+ height,
+ noLegend
+ } = props;
- const theme: any = useTheme();
- const data = useChartData(labels, datasets, colors, theme.theme, true);
+ const theme: any = useTheme();
+ const data = useChartData(labels, datasets, colors, theme.theme, true);
- const donutChartDefaultConfig = useMemo(() => {
- return {
- cutoutPercentage: 70,
- tooltips: {
- callbacks: {
- label: formatTooltipLabelForPieCharts(categoryAxisFormatter, valueAxisFormatter)
- }
- },
- plugins: {
- datalabels: {
- anchor: 'end',
- align: 'end',
- color: (context) => {
- return /* sapUiBaseText */ '#32363a';
- },
- formatter: valueAxisFormatter
- }
+ const donutChartDefaultConfig = useMemo(() => {
+ return {
+ cutoutPercentage: 70,
+ tooltips: {
+ callbacks: {
+ label: formatTooltipLabelForPieCharts(categoryAxisFormatter, valueAxisFormatter)
}
- };
- }, [categoryAxisFormatter, valueAxisFormatter]);
-
- const mergedOptions = useMergedConfig(donutChartDefaultConfig, options);
+ },
+ plugins: {
+ datalabels: {
+ anchor: 'end',
+ align: 'end',
+ color: (context) => {
+ return /* sapUiBaseText */ '#32363a';
+ },
+ formatter: valueAxisFormatter
+ }
+ }
+ };
+ }, [categoryAxisFormatter, valueAxisFormatter]);
- const chartRef = useConsolidatedRef(ref);
- const legendRef: RefObject = useRef();
+ const mergedOptions = useMergedConfig(donutChartDefaultConfig, options);
- const handleLegendItemPress = useCallback(
- (e) => {
- const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
- const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
- const { chartInstance } = chartRef.current;
- const meta = chartInstance.getDatasetMeta(0).data[datasetIndex];
- meta.hidden = !meta.hidden;
- chartInstance.update();
- clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
- },
- [legendRef.current, chartRef.current]
- );
+ const chartRef = useConsolidatedRef(ref);
+ const legendRef: RefObject = useRef();
- useEffect(() => {
- if (noLegend) {
- legendRef.current.innerHTML = '';
- } else {
- legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
- legendRef.current.querySelectorAll('li').forEach((legendItem) => {
- legendItem.addEventListener('click', handleLegendItemPress);
- });
- }
- }, [chartRef.current, legendRef.current, noLegend]);
+ const handleLegendItemPress = useCallback(
+ (e) => {
+ const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
+ const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
+ const { chartInstance } = chartRef.current;
+ const meta = chartInstance.getDatasetMeta(0).data[datasetIndex];
+ meta.hidden = !meta.hidden;
+ chartInstance.update();
+ clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
+ },
+ [legendRef.current, chartRef.current]
+ );
- return (
- <>
-
-
- >
- );
- })
-);
+ useEffect(() => {
+ if (noLegend) {
+ legendRef.current.innerHTML = '';
+ } else {
+ legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
+ legendRef.current.querySelectorAll('li').forEach((legendItem) => {
+ legendItem.addEventListener('click', handleLegendItemPress);
+ });
+ }
+ }, [chartRef.current, legendRef.current, noLegend]);
+ return (
+ <>
+
+
+ >
+ );
+});
// @ts-ignore
-DonutChart.LoadingPlaceholder = PieChartPlaceholder;
+DonutChartComponent.LoadingPlaceholder = PieChartPlaceholder;
+
+const DonutChart = withChartContainer(DonutChartComponent);
+
DonutChart.defaultProps = {
...ChartBaseDefaultProps,
colors: null
diff --git a/packages/charts/src/components/LineChart/LineChart.test.tsx b/packages/charts/src/components/LineChart/LineChart.test.tsx
index 5efd8ff94d7..a1edc0f01ca 100644
--- a/packages/charts/src/components/LineChart/LineChart.test.tsx
+++ b/packages/charts/src/components/LineChart/LineChart.test.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { renderThemedComponent } from '@shared/tests/utils';
+import { mountThemedComponent, renderThemedComponent } from '@shared/tests/utils';
import { LineChart } from './index';
import { labels, singleDataset } from '../../test/resources/ChartProps';
@@ -7,4 +7,9 @@ describe('LineChart', () => {
test('Renders with data', () => {
renderThemedComponent();
});
+
+ test('loading placeholder', () => {
+ const wrapper = mountThemedComponent();
+ expect(wrapper.render()).toMatchSnapshot();
+ });
});
diff --git a/packages/charts/src/components/LineChart/__snapshots__/LineChart.test.tsx.snap b/packages/charts/src/components/LineChart/__snapshots__/LineChart.test.tsx.snap
new file mode 100644
index 00000000000..cad5958905b
--- /dev/null
+++ b/packages/charts/src/components/LineChart/__snapshots__/LineChart.test.tsx.snap
@@ -0,0 +1,81 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`LineChart loading placeholder 1`] = `
+
+
+
+`;
diff --git a/packages/charts/src/components/LineChart/demo.stories.tsx b/packages/charts/src/components/LineChart/demo.stories.tsx
index 104cb2b4c88..1a26017c02d 100644
--- a/packages/charts/src/components/LineChart/demo.stories.tsx
+++ b/packages/charts/src/components/LineChart/demo.stories.tsx
@@ -27,4 +27,5 @@ const renderStoryWithCustomColors = () => (
storiesOf('Charts | Line Chart', module)
.add('Default', renderStory)
.add('with custom colors', renderStoryWithCustomColors)
- .add('with Formatter', renderStoryWithFormatter);
+ .add('with Formatter', renderStoryWithFormatter)
+ .add('Loading Placeholder', () => );
diff --git a/packages/charts/src/components/LineChart/index.tsx b/packages/charts/src/components/LineChart/index.tsx
index dfa7d04eaf0..30abcf2f781 100644
--- a/packages/charts/src/components/LineChart/index.tsx
+++ b/packages/charts/src/components/LineChart/index.tsx
@@ -12,99 +12,99 @@ import { LineChartPlaceholder } from './Placeholder';
export interface LineChartPropTypes extends ChartBaseProps {}
-const LineChart = withChartContainer(
- forwardRef((props: LineChartPropTypes, ref: Ref) => {
- const {
- labels,
- datasets,
- colors,
- options,
- valueAxisFormatter,
- categoryAxisFormatter,
- getElementAtEvent,
- getDatasetAtEvent,
- width,
- height,
- noLegend
- } = props;
+const LineChartComponent = forwardRef((props: LineChartPropTypes, ref: Ref) => {
+ const {
+ labels,
+ datasets,
+ colors,
+ options,
+ valueAxisFormatter,
+ categoryAxisFormatter,
+ getElementAtEvent,
+ getDatasetAtEvent,
+ width,
+ height,
+ noLegend
+ } = props;
- const lineChartDefaultConfig = useMemo(() => {
- return {
- scales: {
- yAxes: [
- {
- ...DEFAULT_OPTIONS.scales.yAxes[0],
- display: true,
- ticks: {
- ...DEFAULT_OPTIONS.scales.yAxes[0].ticks,
- callback: valueAxisFormatter
- }
+ const lineChartDefaultConfig = useMemo(() => {
+ return {
+ scales: {
+ yAxes: [
+ {
+ ...DEFAULT_OPTIONS.scales.yAxes[0],
+ display: true,
+ ticks: {
+ ...DEFAULT_OPTIONS.scales.yAxes[0].ticks,
+ callback: valueAxisFormatter
}
- ],
- xAxes: DEFAULT_OPTIONS.scales.xAxes
- },
- tooltips: {
- callbacks: {
- label: formatTooltipLabel(categoryAxisFormatter, valueAxisFormatter)
- }
- },
- plugins: {
- datalabels: {
- formatter: valueAxisFormatter
}
+ ],
+ xAxes: DEFAULT_OPTIONS.scales.xAxes
+ },
+ tooltips: {
+ callbacks: {
+ label: formatTooltipLabel(categoryAxisFormatter, valueAxisFormatter)
}
- };
- }, [categoryAxisFormatter, valueAxisFormatter]);
- const chartOptions = useMergedConfig(lineChartDefaultConfig, options);
-
- const theme: any = useTheme();
- const data = useChartData(labels, datasets, colors, theme.theme);
-
- const chartRef = useConsolidatedRef(ref);
- const legendRef: RefObject = useRef();
- const handleLegendItemPress = useCallback(
- (e) => {
- const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
- const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
- const { chartInstance } = chartRef.current;
- const meta = chartInstance.getDatasetMeta(datasetIndex);
- meta.hidden = meta.hidden === null ? !chartInstance.data.datasets[datasetIndex].hidden : null;
- chartInstance.update();
- clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
},
- [legendRef.current, chartRef.current]
- );
-
- useEffect(() => {
- if (noLegend) {
- legendRef.current.innerHTML = '';
- } else {
- legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
- legendRef.current.querySelectorAll('li').forEach((legendItem) => {
- legendItem.addEventListener('click', handleLegendItemPress);
- });
+ plugins: {
+ datalabels: {
+ formatter: valueAxisFormatter
+ }
}
- }, [chartRef.current, legendRef.current, noLegend]);
+ };
+ }, [categoryAxisFormatter, valueAxisFormatter]);
+ const chartOptions = useMergedConfig(lineChartDefaultConfig, options);
+
+ const theme: any = useTheme();
+ const data = useChartData(labels, datasets, colors, theme.theme);
+
+ const chartRef = useConsolidatedRef(ref);
+ const legendRef: RefObject = useRef();
+ const handleLegendItemPress = useCallback(
+ (e) => {
+ const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
+ const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
+ const { chartInstance } = chartRef.current;
+ const meta = chartInstance.getDatasetMeta(datasetIndex);
+ meta.hidden = meta.hidden === null ? !chartInstance.data.datasets[datasetIndex].hidden : null;
+ chartInstance.update();
+ clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
+ },
+ [legendRef.current, chartRef.current]
+ );
- return (
- <>
-
-
- >
- );
- })
-);
+ useEffect(() => {
+ if (noLegend) {
+ legendRef.current.innerHTML = '';
+ } else {
+ legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
+ legendRef.current.querySelectorAll('li').forEach((legendItem) => {
+ legendItem.addEventListener('click', handleLegendItemPress);
+ });
+ }
+ }, [chartRef.current, legendRef.current, noLegend]);
+ return (
+ <>
+
+
+ >
+ );
+});
// @ts-ignore
-LineChart.LoadingPlaceholder = LineChartPlaceholder;
+LineChartComponent.LoadingPlaceholder = LineChartPlaceholder;
+
+const LineChart = withChartContainer(LineChartComponent);
+
LineChart.defaultProps = {
...ChartBaseDefaultProps
};
diff --git a/packages/charts/src/components/PieChart/PieChart.test.tsx b/packages/charts/src/components/PieChart/PieChart.test.tsx
index 8001c6f98b4..4c40fc42a8a 100644
--- a/packages/charts/src/components/PieChart/PieChart.test.tsx
+++ b/packages/charts/src/components/PieChart/PieChart.test.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { renderThemedComponent } from '@shared/tests/utils';
+import { mountThemedComponent, renderThemedComponent } from '@shared/tests/utils';
import { PieChart } from './index';
import { labels, singleDataset } from '../../test/resources/ChartProps';
@@ -7,4 +7,9 @@ describe('PieChart', () => {
test('Renders with data', () => {
renderThemedComponent();
});
+
+ test('loading placeholder', () => {
+ const wrapper = mountThemedComponent();
+ expect(wrapper.render()).toMatchSnapshot();
+ });
});
diff --git a/packages/charts/src/components/PieChart/__snapshots__/PieChart.test.tsx.snap b/packages/charts/src/components/PieChart/__snapshots__/PieChart.test.tsx.snap
new file mode 100644
index 00000000000..47f07d1dbfd
--- /dev/null
+++ b/packages/charts/src/components/PieChart/__snapshots__/PieChart.test.tsx.snap
@@ -0,0 +1,81 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`PieChart loading placeholder 1`] = `
+
+
+
+`;
diff --git a/packages/charts/src/components/PieChart/demo.stories.tsx b/packages/charts/src/components/PieChart/demo.stories.tsx
index a47eb96fa88..61061cf487a 100644
--- a/packages/charts/src/components/PieChart/demo.stories.tsx
+++ b/packages/charts/src/components/PieChart/demo.stories.tsx
@@ -10,4 +10,5 @@ storiesOf('Charts | PieChart', module)
.add('Default', () => )
.add('with Formatter', () => (
`${d}%`} loading={boolean('loading')} />
- ));
+ ))
+ .add('Loading Placeholder', () => );
diff --git a/packages/charts/src/components/PieChart/index.tsx b/packages/charts/src/components/PieChart/index.tsx
index d73791f8ff1..bc500769580 100644
--- a/packages/charts/src/components/PieChart/index.tsx
+++ b/packages/charts/src/components/PieChart/index.tsx
@@ -11,93 +11,93 @@ import { PieChartPlaceholder } from './Placeholder';
export interface PieChartPropTypes extends ChartBaseProps {}
-const PieChart = withChartContainer(
- forwardRef((props: PieChartPropTypes, ref: Ref) => {
- const {
- labels,
- datasets,
- colors,
- categoryAxisFormatter,
- getDatasetAtEvent,
- getElementAtEvent,
- valueAxisFormatter,
- options,
- width,
- height,
- noLegend
- } = props;
+const PieChartComponent = forwardRef((props: PieChartPropTypes, ref: Ref) => {
+ const {
+ labels,
+ datasets,
+ colors,
+ categoryAxisFormatter,
+ getDatasetAtEvent,
+ getElementAtEvent,
+ valueAxisFormatter,
+ options,
+ width,
+ height,
+ noLegend
+ } = props;
- const theme: any = useTheme();
- const data = useChartData(labels, datasets, colors, theme.theme, true);
+ const theme: any = useTheme();
+ const data = useChartData(labels, datasets, colors, theme.theme, true);
- const pieChartDefaultConfig = useMemo(() => {
- return {
- tooltips: {
- callbacks: {
- label: formatTooltipLabelForPieCharts(categoryAxisFormatter, valueAxisFormatter)
- }
- },
- plugins: {
- datalabels: {
- anchor: 'end',
- align: 'end',
- color: (context) => {
- return /* sapUiBaseText */ '#32363a';
- },
- formatter: valueAxisFormatter
- }
+ const pieChartDefaultConfig = useMemo(() => {
+ return {
+ tooltips: {
+ callbacks: {
+ label: formatTooltipLabelForPieCharts(categoryAxisFormatter, valueAxisFormatter)
}
- };
- }, [categoryAxisFormatter, valueAxisFormatter]);
-
- const mergedOptions = useMergedConfig(pieChartDefaultConfig, options);
+ },
+ plugins: {
+ datalabels: {
+ anchor: 'end',
+ align: 'end',
+ color: (context) => {
+ return /* sapUiBaseText */ '#32363a';
+ },
+ formatter: valueAxisFormatter
+ }
+ }
+ };
+ }, [categoryAxisFormatter, valueAxisFormatter]);
- const chartRef = useConsolidatedRef(ref);
- const legendRef: RefObject = useRef();
+ const mergedOptions = useMergedConfig(pieChartDefaultConfig, options);
- const handleLegendItemPress = useCallback(
- (e) => {
- const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
- const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
- const { chartInstance } = chartRef.current;
- const meta = chartInstance.getDatasetMeta(0).data[datasetIndex];
- meta.hidden = !meta.hidden;
- chartInstance.update();
- clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
- },
- [legendRef.current, chartRef.current]
- );
+ const chartRef = useConsolidatedRef(ref);
+ const legendRef: RefObject = useRef();
- useEffect(() => {
- if (noLegend) {
- legendRef.current.innerHTML = '';
- } else {
- legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
- legendRef.current.querySelectorAll('li').forEach((legendItem) => {
- legendItem.addEventListener('click', handleLegendItemPress);
- });
- }
- }, [chartRef.current, legendRef.current, noLegend]);
+ const handleLegendItemPress = useCallback(
+ (e) => {
+ const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
+ const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
+ const { chartInstance } = chartRef.current;
+ const meta = chartInstance.getDatasetMeta(0).data[datasetIndex];
+ meta.hidden = !meta.hidden;
+ chartInstance.update();
+ clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
+ },
+ [legendRef.current, chartRef.current]
+ );
- return (
- <>
-
-
- >
- );
- })
-);
+ useEffect(() => {
+ if (noLegend) {
+ legendRef.current.innerHTML = '';
+ } else {
+ legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
+ legendRef.current.querySelectorAll('li').forEach((legendItem) => {
+ legendItem.addEventListener('click', handleLegendItemPress);
+ });
+ }
+ }, [chartRef.current, legendRef.current, noLegend]);
+ return (
+ <>
+
+
+ >
+ );
+});
// @ts-ignore
-PieChart.LoadingPlaceholder = PieChartPlaceholder;
+PieChartComponent.LoadingPlaceholder = PieChartPlaceholder;
+
+const PieChart = withChartContainer(PieChartComponent);
+
PieChart.defaultProps = {
...ChartBaseDefaultProps
};
diff --git a/packages/charts/src/components/RadarChart/index.tsx b/packages/charts/src/components/RadarChart/index.tsx
index 63ebcf1ff6b..f8774fc86c1 100644
--- a/packages/charts/src/components/RadarChart/index.tsx
+++ b/packages/charts/src/components/RadarChart/index.tsx
@@ -10,86 +10,85 @@ import { formatTooltipLabel, useMergedConfig } from '../../util/utils';
export interface RadarChartPropTypes extends ChartBaseProps {}
-const RadarChart: FC = withChartContainer(
- forwardRef((props: RadarChartPropTypes, ref: Ref) => {
- const {
- labels,
- datasets,
- width,
- height,
- options,
- categoryAxisFormatter,
- getDatasetAtEvent,
- getElementAtEvent,
- valueAxisFormatter,
- colors,
- noLegend
- } = props;
+const RadarChartComponent = forwardRef((props: RadarChartPropTypes, ref: Ref) => {
+ const {
+ labels,
+ datasets,
+ width,
+ height,
+ options,
+ categoryAxisFormatter,
+ getDatasetAtEvent,
+ getElementAtEvent,
+ valueAxisFormatter,
+ colors,
+ noLegend
+ } = props;
- const theme: any = useTheme();
- const data = useChartData(labels, datasets, colors, theme.theme);
+ const theme: any = useTheme();
+ const data = useChartData(labels, datasets, colors, theme.theme);
- const radarChartDefaultConfig = useMemo(() => {
- return {
- scale: {
- ticks: {
- callback: valueAxisFormatter
- }
- },
- tooltips: {
- callbacks: {
- label: formatTooltipLabel(categoryAxisFormatter, valueAxisFormatter)
- }
- },
- plugins: {
- datalabels: false
+ const radarChartDefaultConfig = useMemo(() => {
+ return {
+ scale: {
+ ticks: {
+ callback: valueAxisFormatter
}
- };
- }, [categoryAxisFormatter, valueAxisFormatter]);
- const mergedOptions = useMergedConfig(radarChartDefaultConfig, options);
-
- const chartRef = useConsolidatedRef(ref);
- const legendRef: RefObject = useRef();
- const handleLegendItemPress = useCallback(
- (e) => {
- const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
- const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
- const { chartInstance } = chartRef.current;
- const meta = chartInstance.getDatasetMeta(datasetIndex);
- meta.hidden = meta.hidden === null ? !chartInstance.data.datasets[datasetIndex].hidden : null;
- chartInstance.update();
- clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
},
- [legendRef.current, chartRef.current]
- );
-
- useEffect(() => {
- if (noLegend) {
- legendRef.current.innerHTML = '';
- } else {
- legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
- legendRef.current.querySelectorAll('li').forEach((legendItem) => {
- legendItem.addEventListener('click', handleLegendItemPress);
- });
+ tooltips: {
+ callbacks: {
+ label: formatTooltipLabel(categoryAxisFormatter, valueAxisFormatter)
+ }
+ },
+ plugins: {
+ datalabels: false
}
- }, [chartRef.current, legendRef.current, noLegend]);
+ };
+ }, [categoryAxisFormatter, valueAxisFormatter]);
+ const mergedOptions = useMergedConfig(radarChartDefaultConfig, options);
+
+ const chartRef = useConsolidatedRef(ref);
+ const legendRef: RefObject = useRef();
+ const handleLegendItemPress = useCallback(
+ (e) => {
+ const clickTarget = (e.currentTarget as unknown) as HTMLLIElement;
+ const datasetIndex = parseInt(clickTarget.dataset.datasetindex);
+ const { chartInstance } = chartRef.current;
+ const meta = chartInstance.getDatasetMeta(datasetIndex);
+ meta.hidden = meta.hidden === null ? !chartInstance.data.datasets[datasetIndex].hidden : null;
+ chartInstance.update();
+ clickTarget.style.textDecoration = meta.hidden ? 'line-through' : 'unset';
+ },
+ [legendRef.current, chartRef.current]
+ );
+
+ useEffect(() => {
+ if (noLegend) {
+ legendRef.current.innerHTML = '';
+ } else {
+ legendRef.current.innerHTML = chartRef.current.chartInstance.generateLegend();
+ legendRef.current.querySelectorAll('li').forEach((legendItem) => {
+ legendItem.addEventListener('click', handleLegendItemPress);
+ });
+ }
+ }, [chartRef.current, legendRef.current, noLegend]);
- return (
- <>
- {' '}
-
- >
- );
- })
-);
+ return (
+ <>
+ {' '}
+
+ >
+ );
+});
+const RadarChart = withChartContainer(RadarChartComponent);
RadarChart.defaultProps = {
...ChartBaseDefaultProps
diff --git a/shared/tests/serializer/content-loader-serializer.js b/shared/tests/serializer/content-loader-serializer.js
new file mode 100644
index 00000000000..f75f9b3b606
--- /dev/null
+++ b/shared/tests/serializer/content-loader-serializer.js
@@ -0,0 +1,66 @@
+// removing dynamic class names as well as code coverage instrumentation added by
+// istanbul-instrumenter-loader
+
+const MARKER = '__content-loader-serializer-marker__';
+const styleUrl = /fill: url\(#([\d\w)]+)\)/i;
+
+const collectElements = (element, elements = []) => {
+ if (typeof element !== 'object') {
+ return elements;
+ }
+
+ elements.push(element);
+
+ if (element.children) {
+ element.children.forEach((child) => collectElements(child, elements));
+ }
+
+ return elements;
+};
+
+const markElements = (elements) =>
+ elements.forEach((element) => {
+ element[MARKER] = true;
+ });
+
+const replaceIds = (elements) => {
+ elements.forEach((element) => {
+ if (element.node.name === 'clipPath' || element.props['clip-path'] || element.node.name === 'linearGradient') {
+ if (element.props['clip-path']) {
+ element.props['clip-path'] = 'CLIP-PATH-URL';
+ }
+
+ if (element.props.style) {
+ element.props.style = element.props.style.replace(styleUrl, (a, b) => {
+ return a.replace(b, 'STYLE-URL');
+ });
+ }
+
+ if (element.node.name === 'clipPath') {
+ element.props.id = 'CLIP-PATH-URL';
+ }
+
+ if (element.node.name === 'linearGradient') {
+ element.props.id = 'STYLE-URL';
+ }
+ }
+ });
+};
+
+module.exports = {
+ test(value) {
+ return value && !value[MARKER] && value.$$typeof === Symbol.for('react.test.json');
+ },
+
+ print(value, serialize) {
+ // collect all react element nodes in the tree of the value
+ const elements = collectElements(value);
+
+ // mark the collected element nodes to avoid processing them several times
+ markElements(elements);
+
+ replaceIds(elements);
+
+ return serialize(value);
+ }
+};