@spaced-out/ui-design-system 0.3.17 → 0.3.18

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.3.18](https://github.com/spaced-out/ui-design-system/compare/v0.3.17...v0.3.18) (2025-01-23)
6
+
7
+
8
+ ### Features
9
+
10
+ * funnel chart ([#311](https://github.com/spaced-out/ui-design-system/issues/311)) ([7a19cb8](https://github.com/spaced-out/ui-design-system/commit/7a19cb820393249579a54929e968ce4a3afa2337))
11
+
5
12
  ### [0.3.17](https://github.com/spaced-out/ui-design-system/compare/v0.3.16...v0.3.17) (2025-01-16)
6
13
 
7
14
 
package/CONTRIBUTING.md CHANGED
@@ -174,7 +174,7 @@ For every change in `ui_design_system` that you want to propagate to `consumer`
174
174
  > in `consumer`
175
175
 
176
176
  ```bash
177
- yarn upgrade @spaced-out/ui-design-system@file:../../ui-design-system
177
+ yarn upgrade @spaced-out/ui-design-system@file:../ui-design-system
178
178
  ```
179
179
 
180
180
  ## Troubleshooting local development
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FunnelChart = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _highcharts = _interopRequireDefault(require("highcharts"));
9
+ var _funnel = _interopRequireDefault(require("highcharts/modules/funnel"));
10
+ var _highchartsReactOfficial = _interopRequireDefault(require("highcharts-react-official"));
11
+ var _charts = require("../../../utils/charts");
12
+ var _funnelChart = require("../../../utils/charts/funnelChart");
13
+ var _classify = _interopRequireDefault(require("../../../utils/classify"));
14
+ var _ChartWrapper = require("../ChartWrapper");
15
+ var _FunnelChartModule = _interopRequireDefault(require("./FunnelChart.module.css"));
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
18
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
+
20
+ //$FlowFixMe[untyped-import]
21
+
22
+ //$FlowFixMe[untyped-import]
23
+
24
+ //$FlowFixMe[untyped-import]
25
+
26
+ const FunnelChart = _ref => {
27
+ let {
28
+ isLoading,
29
+ classNames,
30
+ cardTitle,
31
+ customExportOptions,
32
+ series,
33
+ headerActions,
34
+ drilldown,
35
+ showLegend = true,
36
+ ...userOptions
37
+ } = _ref;
38
+ (0, _funnel.default)(_highcharts.default);
39
+ const chartRef = /*#__PURE__*/React.createRef();
40
+ const funnelChartSeries = (0, _funnelChart.addColorsToFunnelSeries)(series, showLegend);
41
+ const defaultFunnelChartOptions = (0, _funnelChart.getFunnelChartOptions)();
42
+ const columnDrilldown = drilldown ? {
43
+ ...(0, _funnelChart.addColorsToFunnelDrilldownSeries)(drilldown, showLegend),
44
+ breadcrumbs: {
45
+ floating: false
46
+ }
47
+ } : {};
48
+
49
+ //$FlowFixMe[cannot-spread-inexact]
50
+ const chartOptions = (0, _charts.mergeChartUserOptions)(defaultFunnelChartOptions, {
51
+ series: funnelChartSeries,
52
+ drilldown: columnDrilldown,
53
+ ...userOptions
54
+ });
55
+ const {
56
+ highChart,
57
+ ...wrapperClassNames
58
+ } = classNames || {};
59
+ return /*#__PURE__*/React.createElement(_ChartWrapper.ChartWrapper, {
60
+ isLoading: isLoading,
61
+ title: cardTitle,
62
+ ref: chartRef,
63
+ classNames: wrapperClassNames,
64
+ customExportOptions: customExportOptions,
65
+ headerActions: headerActions
66
+ }, /*#__PURE__*/React.createElement(_highchartsReactOfficial.default, {
67
+ highcharts: _highcharts.default,
68
+ containerProps: {
69
+ className: (0, _classify.default)(_FunnelChartModule.default.funnelChartContainer, highChart)
70
+ },
71
+ ref: chartRef,
72
+ options: chartOptions
73
+ }));
74
+ };
75
+ exports.FunnelChart = FunnelChart;
@@ -0,0 +1,109 @@
1
+ // @flow strict
2
+
3
+ import * as React from 'react';
4
+ //$FlowFixMe[untyped-import]
5
+ import Highcharts from 'highcharts';
6
+ //$FlowFixMe[untyped-import]
7
+ import Funnel from 'highcharts/modules/funnel';
8
+ //$FlowFixMe[untyped-import]
9
+ import HighchartsReact from 'highcharts-react-official';
10
+
11
+ import type {
12
+ ChartOptions,
13
+ DataOptionsType,
14
+ Drilldown,
15
+ } from '../../../types/charts';
16
+ import {mergeChartUserOptions} from '../../../utils/charts';
17
+ import {
18
+ addColorsToFunnelDrilldownSeries,
19
+ addColorsToFunnelSeries,
20
+ getFunnelChartOptions,
21
+ } from '../../../utils/charts/funnelChart';
22
+ import classify from '../../../utils/classify';
23
+ import {
24
+ type ChartWrapperClassNames,
25
+ type ExportOptionType,
26
+ ChartWrapper,
27
+ } from '../ChartWrapper';
28
+
29
+ import css from './FunnelChart.module.css';
30
+
31
+
32
+ export type ClassNames = $ReadOnly<{
33
+ ...ChartWrapperClassNames,
34
+ highChart?: string,
35
+ }>;
36
+
37
+ export type FunnelSeriesItem = {
38
+ name?: string,
39
+ showInLegend?: boolean,
40
+ data: Array<DataOptionsType>,
41
+ };
42
+
43
+ export type FunnelChartProps = {
44
+ ...ChartOptions,
45
+ isLoading?: boolean,
46
+ classNames?: ClassNames,
47
+ cardTitle?: React.Node,
48
+ customExportOptions?: Array<ExportOptionType> | null,
49
+ series: Array<FunnelSeriesItem>,
50
+ headerActions?: React.Node,
51
+ drilldown?: Drilldown,
52
+ showLegend?: boolean,
53
+ ...
54
+ };
55
+
56
+ export const FunnelChart = ({
57
+ isLoading,
58
+ classNames,
59
+ cardTitle,
60
+ customExportOptions,
61
+ series,
62
+ headerActions,
63
+ drilldown,
64
+ showLegend = true,
65
+ ...userOptions
66
+ }: FunnelChartProps): React.Node => {
67
+ Funnel(Highcharts);
68
+ const chartRef = React.createRef();
69
+
70
+ const funnelChartSeries = addColorsToFunnelSeries(series, showLegend);
71
+
72
+ const defaultFunnelChartOptions = getFunnelChartOptions();
73
+
74
+ const columnDrilldown = drilldown
75
+ ? {
76
+ ...addColorsToFunnelDrilldownSeries(drilldown, showLegend),
77
+ breadcrumbs: {floating: false},
78
+ }
79
+ : {};
80
+
81
+ //$FlowFixMe[cannot-spread-inexact]
82
+ const chartOptions = mergeChartUserOptions(defaultFunnelChartOptions, {
83
+ series: funnelChartSeries,
84
+ drilldown: columnDrilldown,
85
+ ...userOptions,
86
+ });
87
+
88
+ const {highChart, ...wrapperClassNames} = classNames || {};
89
+
90
+ return (
91
+ <ChartWrapper
92
+ isLoading={isLoading}
93
+ title={cardTitle}
94
+ ref={chartRef}
95
+ classNames={wrapperClassNames}
96
+ customExportOptions={customExportOptions}
97
+ headerActions={headerActions}
98
+ >
99
+ <HighchartsReact
100
+ highcharts={Highcharts}
101
+ containerProps={{
102
+ className: classify(css.funnelChartContainer, highChart),
103
+ }}
104
+ ref={chartRef}
105
+ options={chartOptions}
106
+ />
107
+ </ChartWrapper>
108
+ );
109
+ };
@@ -0,0 +1,17 @@
1
+ @value (colorFillPrimary) from '../../../styles/variables/_color.css';
2
+ @value (size400, size660, sizeFluid) from '../../../styles/variables/_size.css';
3
+
4
+ .wrapper {
5
+ display: flex;
6
+ flex-direction: column;
7
+ }
8
+
9
+ .funnelChartContainer {
10
+ width: sizeFluid;
11
+ min-width: size660;
12
+ min-height: size400;
13
+ max-height: size400;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ var _FunnelChart = require("./FunnelChart");
7
+ Object.keys(_FunnelChart).forEach(function (key) {
8
+ if (key === "default" || key === "__esModule") return;
9
+ if (key in exports && exports[key] === _FunnelChart[key]) return;
10
+ Object.defineProperty(exports, key, {
11
+ enumerable: true,
12
+ get: function () {
13
+ return _FunnelChart[key];
14
+ }
15
+ });
16
+ });
@@ -0,0 +1,3 @@
1
+ // @flow strict
2
+
3
+ export * from './FunnelChart';
@@ -47,6 +47,17 @@ Object.keys(_DonutChart).forEach(function (key) {
47
47
  }
48
48
  });
49
49
  });
50
+ var _FunnelChart = require("./FunnelChart");
51
+ Object.keys(_FunnelChart).forEach(function (key) {
52
+ if (key === "default" || key === "__esModule") return;
53
+ if (key in exports && exports[key] === _FunnelChart[key]) return;
54
+ Object.defineProperty(exports, key, {
55
+ enumerable: true,
56
+ get: function () {
57
+ return _FunnelChart[key];
58
+ }
59
+ });
60
+ });
50
61
  var _LineChart = require("./LineChart");
51
62
  Object.keys(_LineChart).forEach(function (key) {
52
63
  if (key === "default" || key === "__esModule") return;
@@ -4,5 +4,6 @@ export * from './ChartTooltip';
4
4
  export * from './ChartWrapper';
5
5
  export * from './ColumnChart';
6
6
  export * from './DonutChart';
7
+ export * from './FunnelChart';
7
8
  export * from './LineChart';
8
9
  export * from './SpiderChart';
@@ -143,6 +143,7 @@ export type DataOptionsType = {
143
143
  name?: string,
144
144
  color?: string,
145
145
  drilldown?: string,
146
+ id?: string,
146
147
  ...
147
148
  };
148
149
 
@@ -162,7 +163,7 @@ export type Drilldown = {
162
163
  };
163
164
 
164
165
  export type PlotOptionsType = {
165
- ['pie' | 'line']: {
166
+ ['pie' | 'line' | 'funnel']: {
166
167
  innerSize?: string,
167
168
  allowPointSelect?: boolean,
168
169
  cursor?: 'pointer',
@@ -170,6 +171,9 @@ export type PlotOptionsType = {
170
171
  enabled?: boolean,
171
172
  distance?: number,
172
173
  connectorColor?: string,
174
+ useHTML?: boolean,
175
+ format?: string,
176
+ style?: CSSObject,
173
177
  },
174
178
  showInLegend?: boolean,
175
179
  center?: [string, string],
@@ -177,6 +181,10 @@ export type PlotOptionsType = {
177
181
  minSize?: number | string,
178
182
  borderWidth?: number,
179
183
  borderRadius?: number,
184
+ neckWidth?: string | number,
185
+ neckHeight?: string | number,
186
+ minSize?: string | number,
187
+ width?: string | number,
180
188
  ...
181
189
  },
182
190
  };
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getFunnelChartOptions = exports.addColorsToFunnelSeries = exports.addColorsToFunnelDrilldownSeries = void 0;
7
+ var _color = require("../../styles/variables/_color.js");
8
+ var _charts = require("./charts");
9
+ var _helpers = require("./helpers");
10
+ var _typography = require("./typography");
11
+
12
+ /**
13
+ * This function modifies the the common chart behavior to funnel chart default behavior.
14
+ * It will not take userPassed option into account.
15
+ */
16
+
17
+ const getFunnelChartOptions = () => ({
18
+ ..._charts.commonChartOptions,
19
+ chart: {
20
+ type: 'funnel'
21
+ },
22
+ legend: {
23
+ ..._charts.commonChartOptions.legend,
24
+ ..._helpers.bottomLegendRow,
25
+ symbolWidth: 18
26
+ },
27
+ xAxis: {
28
+ ..._charts.commonChartOptions.xAxis,
29
+ labels: {
30
+ style: _typography.formLabelSmall
31
+ },
32
+ title: {
33
+ margin: 12,
34
+ style: _helpers.xAxisTitleStyle
35
+ },
36
+ lineColor: _color.colorBorderPrimary
37
+ },
38
+ yAxis: {
39
+ labels: {
40
+ align: 'right',
41
+ distance: 12,
42
+ style: _helpers.yAxisLabelStyle
43
+ },
44
+ title: {
45
+ margin: 12,
46
+ style: _helpers.yAxisTitleStyle
47
+ }
48
+ },
49
+ plotOptions: {
50
+ funnel: {
51
+ neckWidth: '15%',
52
+ neckHeight: '10%',
53
+ minSize: '50%',
54
+ width: '55%',
55
+ dataLabels: {
56
+ enabled: true,
57
+ useHTML: true,
58
+ // Allows custom HTML formatting
59
+ format: `<div style="text-align: center">
60
+ <span>{point.name}</span><br>
61
+ <span>{point.y}</span>
62
+ </div>`,
63
+ style: {
64
+ fontWeight: 'bold'
65
+ }
66
+ }
67
+ }
68
+ }
69
+ });
70
+ exports.getFunnelChartOptions = getFunnelChartOptions;
71
+ const addColorsToFunnelSeries = function (series) {
72
+ let showInLegend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
73
+ return series.map(item => ({
74
+ ...item,
75
+ data: item.data.map((seriesItem, index) => ({
76
+ ...seriesItem,
77
+ color: (0, _charts.getDataVizColor)(index) // Apply color based on index
78
+ })),
79
+
80
+ showInLegend // Ensure legend visibility
81
+ }));
82
+ };
83
+ exports.addColorsToFunnelSeries = addColorsToFunnelSeries;
84
+ const addColorsToFunnelDrilldownSeries = function (drilldownSeries) {
85
+ let showInLegend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
86
+ return {
87
+ series: drilldownSeries.series?.map(series => ({
88
+ ...series,
89
+ data: series.data.map((dataPoint, index) => ({
90
+ ...dataPoint,
91
+ color: (0, _charts.getDataVizColor)(index) // Assign a color dynamically based on index
92
+ })),
93
+
94
+ showInLegend // Ensure legend is displayed
95
+ }))
96
+ };
97
+ };
98
+ exports.addColorsToFunnelDrilldownSeries = addColorsToFunnelDrilldownSeries;
@@ -0,0 +1,102 @@
1
+ // @flow strict
2
+ import type {FunnelSeriesItem} from '../../components/Charts/FunnelChart/FunnelChart.js';
3
+ import {colorBorderPrimary} from '../../styles/variables/_color.js';
4
+ import type {
5
+ ChartOptions,
6
+ DataOptionsType,
7
+ Drilldown,
8
+ } from '../../types/charts';
9
+
10
+ import {commonChartOptions, getDataVizColor} from './charts';
11
+ import {
12
+ bottomLegendRow,
13
+ xAxisTitleStyle,
14
+ yAxisLabelStyle,
15
+ yAxisTitleStyle,
16
+ } from './helpers';
17
+ import {formLabelSmall} from './typography';
18
+
19
+ /**
20
+ * This function modifies the the common chart behavior to funnel chart default behavior.
21
+ * It will not take userPassed option into account.
22
+ */
23
+
24
+ export const getFunnelChartOptions = (): ChartOptions => ({
25
+ ...commonChartOptions,
26
+ chart: {
27
+ type: 'funnel',
28
+ },
29
+ legend: {
30
+ ...commonChartOptions.legend,
31
+ ...bottomLegendRow,
32
+ symbolWidth: 18,
33
+ },
34
+ xAxis: {
35
+ ...commonChartOptions.xAxis,
36
+ labels: {
37
+ style: formLabelSmall,
38
+ },
39
+ title: {
40
+ margin: 12,
41
+ style: xAxisTitleStyle,
42
+ },
43
+ lineColor: colorBorderPrimary,
44
+ },
45
+ yAxis: {
46
+ labels: {
47
+ align: 'right',
48
+ distance: 12,
49
+ style: yAxisLabelStyle,
50
+ },
51
+ title: {
52
+ margin: 12,
53
+ style: yAxisTitleStyle,
54
+ },
55
+ },
56
+ plotOptions: {
57
+ funnel: {
58
+ neckWidth: '15%',
59
+ neckHeight: '10%',
60
+ minSize: '50%',
61
+ width: '55%',
62
+ dataLabels: {
63
+ enabled: true,
64
+ useHTML: true, // Allows custom HTML formatting
65
+ format: `<div style="text-align: center">
66
+ <span>{point.name}</span><br>
67
+ <span>{point.y}</span>
68
+ </div>`,
69
+ style: {
70
+ fontWeight: 'bold',
71
+ },
72
+ },
73
+ },
74
+ },
75
+ });
76
+
77
+ export const addColorsToFunnelSeries = (
78
+ series: Array<FunnelSeriesItem>,
79
+ showInLegend?: boolean = true,
80
+ ): Array<FunnelSeriesItem> =>
81
+ series.map((item: FunnelSeriesItem) => ({
82
+ ...item,
83
+ data: item.data.map((seriesItem: DataOptionsType, index: number) => ({
84
+ ...seriesItem,
85
+ color: getDataVizColor(index), // Apply color based on index
86
+ })),
87
+ showInLegend, // Ensure legend visibility
88
+ }));
89
+
90
+ export const addColorsToFunnelDrilldownSeries = (
91
+ drilldownSeries: Drilldown,
92
+ showInLegend?: boolean = true,
93
+ ): Drilldown => ({
94
+ series: drilldownSeries.series?.map((series) => ({
95
+ ...series,
96
+ data: series.data.map((dataPoint, index) => ({
97
+ ...dataPoint,
98
+ color: getDataVizColor(index), // Assign a color dynamically based on index
99
+ })),
100
+ showInLegend, // Ensure legend is displayed
101
+ })),
102
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spaced-out/ui-design-system",
3
- "version": "0.3.17",
3
+ "version": "0.3.18",
4
4
  "main": "index.js",
5
5
  "description": "Sense UI components library",
6
6
  "author": {