@servicetitan/marketing-ui 1.18.0 → 3.0.0

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 (70) hide show
  1. package/dist/components/charts/funnel-chart/components/funnel-chart.js +1 -1
  2. package/dist/components/charts/funnel-chart/components/funnel-chart.js.map +1 -1
  3. package/dist/components/charts/funnel-chart/components/funnel-chart.module.less +1 -1
  4. package/dist/components/charts/funnel-chart/components/funnel-svg.js +1 -1
  5. package/dist/components/charts/funnel-chart/components/funnel-svg.js.map +1 -1
  6. package/dist/components/charts/line-chart/components/body.d.ts.map +1 -1
  7. package/dist/components/charts/line-chart/components/body.js +3 -2
  8. package/dist/components/charts/line-chart/components/body.js.map +1 -1
  9. package/dist/components/charts/line-chart/components/body.module.less +1 -1
  10. package/dist/components/charts/line-chart/components/hover-popover.module.less +1 -1
  11. package/dist/components/charts/line-chart/components/sidebar.module.less +1 -1
  12. package/dist/components/charts/line-chart/components/stuff.module.less +1 -1
  13. package/dist/components/charts/line-chart/components/svg-bars.d.ts +1 -0
  14. package/dist/components/charts/line-chart/components/svg-bars.d.ts.map +1 -1
  15. package/dist/components/charts/line-chart/components/svg-bars.js +8 -1
  16. package/dist/components/charts/line-chart/components/svg-bars.js.map +1 -1
  17. package/dist/components/charts/line-chart/components/svg-body.d.ts.map +1 -1
  18. package/dist/components/charts/line-chart/components/svg-body.js +3 -2
  19. package/dist/components/charts/line-chart/components/svg-body.js.map +1 -1
  20. package/dist/components/charts/line-chart/components/svg.module.less +1 -1
  21. package/dist/components/charts/line-chart/line-chart.stories.d.ts +1 -0
  22. package/dist/components/charts/line-chart/line-chart.stories.d.ts.map +1 -1
  23. package/dist/components/charts/line-chart/line-chart.stories.js +26 -0
  24. package/dist/components/charts/line-chart/line-chart.stories.js.map +1 -1
  25. package/dist/components/charts/line-chart/stores/line-chart.store.js +1 -1
  26. package/dist/components/charts/line-chart/stores/line-chart.store.js.map +1 -1
  27. package/dist/components/charts/line-chart/stores/svg.store.d.ts.map +1 -1
  28. package/dist/components/charts/line-chart/stores/svg.store.js +1 -1
  29. package/dist/components/charts/line-chart/stores/svg.store.js.map +1 -1
  30. package/dist/components/charts/line-chart/utils/formatters.d.ts +1 -1
  31. package/dist/components/charts/line-chart/utils/formatters.d.ts.map +1 -1
  32. package/dist/components/charts/line-chart/utils/interfaces.d.ts +1 -1
  33. package/dist/components/charts/line-chart/utils/interfaces.d.ts.map +1 -1
  34. package/dist/components/charts/pie-chart/components/pie.js +1 -1
  35. package/dist/components/charts/pie-chart/components/pie.js.map +1 -1
  36. package/dist/components/stat/stat-card.module.less +1 -1
  37. package/dist/components/ui/action-button/action-button.module.less +1 -1
  38. package/dist/components/ui/date-range-picker/date-range-picker.module.less +1 -1
  39. package/dist/components/ui/label-with-hint/label-with-hint.js +1 -1
  40. package/dist/components/ui/label-with-hint/label-with-hint.js.map +1 -1
  41. package/dist/components/ui/line-text/line-text.module.less +1 -1
  42. package/dist/components/ui/title-popover/title-popover.module.less +1 -1
  43. package/dist/utils/date/date-range-picker-state.d.ts +1 -1
  44. package/dist/utils/date/date-range-picker-state.d.ts.map +1 -1
  45. package/dist/utils/formatters.d.ts +1 -1
  46. package/dist/utils/formatters.d.ts.map +1 -1
  47. package/package.json +6 -6
  48. package/src/components/charts/funnel-chart/components/funnel-chart.module.less +1 -1
  49. package/src/components/charts/funnel-chart/components/funnel-chart.tsx +1 -1
  50. package/src/components/charts/funnel-chart/components/funnel-svg.tsx +1 -1
  51. package/src/components/charts/line-chart/components/body.module.less +1 -1
  52. package/src/components/charts/line-chart/components/body.tsx +6 -2
  53. package/src/components/charts/line-chart/components/hover-popover.module.less +1 -1
  54. package/src/components/charts/line-chart/components/sidebar.module.less +1 -1
  55. package/src/components/charts/line-chart/components/stuff.module.less +1 -1
  56. package/src/components/charts/line-chart/components/svg-bars.tsx +62 -43
  57. package/src/components/charts/line-chart/components/svg-body.tsx +9 -1
  58. package/src/components/charts/line-chart/components/svg.module.less +1 -1
  59. package/src/components/charts/line-chart/line-chart.stories.tsx +36 -0
  60. package/src/components/charts/line-chart/stores/line-chart.store.ts +1 -1
  61. package/src/components/charts/line-chart/stores/svg.store.ts +3 -1
  62. package/src/components/charts/line-chart/utils/interfaces.ts +1 -1
  63. package/src/components/charts/pie-chart/components/pie.tsx +1 -1
  64. package/src/components/stat/stat-card.module.less +1 -1
  65. package/src/components/ui/action-button/action-button.module.less +1 -1
  66. package/src/components/ui/date-range-picker/date-range-picker.module.less +1 -1
  67. package/src/components/ui/label-with-hint/label-with-hint.tsx +1 -1
  68. package/src/components/ui/line-text/line-text.module.less +1 -1
  69. package/src/components/ui/title-popover/title-popover.module.less +1 -1
  70. package/CHANGELOG.md +0 -353
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/marketing-ui",
3
- "version": "1.18.0",
3
+ "version": "3.0.0",
4
4
  "description": "Marketing UI component and utils",
5
5
  "repository": {
6
6
  "type": "git",
@@ -19,9 +19,9 @@
19
19
  "react-image-crop": "8.6.5"
20
20
  },
21
21
  "peerDependencies": {
22
- "@servicetitan/design-system": "~10.1.1",
22
+ "@servicetitan/design-system": ">=12.4.1",
23
23
  "@servicetitan/react-ioc": "~14.1.1",
24
- "@servicetitan/tokens": "~10.1.1",
24
+ "@servicetitan/tokens": ">=12.1.11",
25
25
  "accounting": "~0.4.1",
26
26
  "mobx": "~6.3.2",
27
27
  "mobx-react": "~7.2.0",
@@ -29,9 +29,9 @@
29
29
  "react": "~17.0.2"
30
30
  },
31
31
  "devDependencies": {
32
- "@servicetitan/design-system": "~10.1.1",
32
+ "@servicetitan/design-system": ">=12.4.1",
33
33
  "@servicetitan/react-ioc": "~14.1.1",
34
- "@servicetitan/tokens": "~10.1.1",
34
+ "@servicetitan/tokens": ">=12.1.11",
35
35
  "@testing-library/react": "^12.0.0",
36
36
  "@types/accounting": "~0.4.2",
37
37
  "@types/history": "~4.7.7",
@@ -51,5 +51,5 @@
51
51
  "less": true,
52
52
  "webpack": false
53
53
  },
54
- "gitHead": "1a8fcbd2b9718d5fc5fb87dbc1aa7974562cf4d1"
54
+ "gitHead": "ae922725e2ed2093afac0864d8f7d76b7e1f2430"
55
55
  }
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .flex1 {
4
4
  flex: 1;
@@ -11,7 +11,7 @@ import {
11
11
  StatusLight,
12
12
  Tooltip,
13
13
  } from '@servicetitan/design-system';
14
- import tokens from '@servicetitan/tokens';
14
+ import { tokens } from '@servicetitan/tokens/core';
15
15
  import { formatValue } from '../../../../utils/formatters';
16
16
  import { StatDiff } from '../../../stat/stat-card';
17
17
  import { FunnelChartProps } from '../utils/interface';
@@ -1,5 +1,5 @@
1
1
  import { useMemo, FC } from 'react';
2
- import tokens from '@servicetitan/tokens';
2
+ import { tokens } from '@servicetitan/tokens/core';
3
3
  import { defaultBottomSideLength, defaultTopSideLength } from '../utils/const';
4
4
 
5
5
  const st = (v: number) => v.toFixed(2);
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .chart-wrapper {
4
4
  height: 440px;
@@ -92,8 +92,12 @@ export const Body: FC<{ classNameTitle?: string }> = provide({ singletons: [SvgS
92
92
  right={right?.width ?? 0}
93
93
  labelsMerged={periods.length !== labels.length}
94
94
  hasBars={
95
- !!metrics.filter(m => m.type === 'bar' || m.type === 'stacked-bar')
96
- .length
95
+ !!metrics.filter(
96
+ m =>
97
+ m.type === 'bar' ||
98
+ m.type === 'stacked-bar' ||
99
+ m.type === 'grouped-bar'
100
+ ).length
97
101
  }
98
102
  />
99
103
  )}
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .line {
4
4
  position: absolute;
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .sidebar {
4
4
  height: 100%;
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .color-tag {
4
4
  width: @spacing-3;
@@ -8,57 +8,76 @@ import { SvgStore } from '../stores/svg.store';
8
8
  interface SvgBarsProps {
9
9
  metrics: ChartMetric[];
10
10
  isStackedBarChart?: boolean;
11
+ isGroupedBarChart?: boolean;
11
12
  }
12
13
 
13
- export const SvgBars: FC<SvgBarsProps> = observer(({ metrics, isStackedBarChart }) => {
14
- const [store] = useDependencies(SvgStore);
15
- const { fpx, fpy, barWidth, length } = store;
16
- const barWidthHalf = barWidth / 2;
17
- const paths = [];
14
+ export const SvgBars: FC<SvgBarsProps> = observer(
15
+ ({ metrics, isStackedBarChart, isGroupedBarChart }) => {
16
+ const [store] = useDependencies(SvgStore);
17
+ const { fpx, fpy, barWidth, length } = store;
18
+ const barWidthHalf = barWidth / 2;
19
+ const paths = [];
18
20
 
19
- for (let i = 0; i < length; i++) {
20
- const x = store.periodX(i);
21
- const values = metrics.map(m => ({
22
- id: m.id,
23
- color: m.valuesOpts?.[i]?.color ?? m.color,
24
- val: store.periodY(m, i),
25
- }));
21
+ for (let i = 0; i < length; i++) {
22
+ const x = store.periodX(i);
23
+ const values = metrics.map(m => ({
24
+ id: m.id,
25
+ color: m.valuesOpts?.[i]?.color ?? m.color,
26
+ val: store.periodY(m, i),
27
+ }));
26
28
 
27
- if (isStackedBarChart) {
28
- let stackedBarHeight = values.reduce((sum, curr) => sum + curr.val, 0);
29
+ if (isStackedBarChart) {
30
+ let stackedBarHeight = values.reduce((sum, curr) => sum + curr.val, 0);
29
31
 
30
- for (const value of values) {
31
- paths.push(
32
- <rect
33
- key={keyVal(value.id, i)}
34
- x={fpx(x - barWidthHalf)}
35
- y={fpy(stackedBarHeight)}
36
- width={fpx(barWidth)}
37
- height={fpx(value.val)}
38
- fill={value.color}
39
- />
40
- );
41
- stackedBarHeight -= value.val;
42
- }
43
- } else {
44
- values.sort((a, b) => b.val - a.val);
45
- for (const value of values) {
46
- paths.push(
47
- <rect
48
- key={keyVal(value.id, i)}
49
- x={fpx(x - barWidthHalf)}
50
- y={fpy(value.val)}
51
- width={fpx(barWidth)}
52
- height={fpx(value.val)}
53
- fill={value.color}
54
- />
55
- );
32
+ for (const value of values) {
33
+ paths.push(
34
+ <rect
35
+ key={keyVal(value.id, i)}
36
+ x={fpx(x - barWidthHalf)}
37
+ y={fpy(stackedBarHeight)}
38
+ width={fpx(barWidth)}
39
+ height={fpx(value.val)}
40
+ fill={value.color}
41
+ />
42
+ );
43
+ stackedBarHeight -= value.val;
44
+ }
45
+ } else if (isGroupedBarChart) {
46
+ for (let j = 0; j < values.length; j++) {
47
+ const groupedBarX = (j * barWidth) / values.length;
48
+ const value = values[j];
49
+
50
+ paths.push(
51
+ <rect
52
+ key={keyVal(value.id, i)}
53
+ x={fpx(x + groupedBarX - barWidthHalf)}
54
+ y={fpy(value.val)}
55
+ width={fpx(barWidth / values.length)}
56
+ height={fpx(value.val)}
57
+ fill={value.color}
58
+ />
59
+ );
60
+ }
61
+ } else {
62
+ values.sort((a, b) => b.val - a.val);
63
+ for (const value of values) {
64
+ paths.push(
65
+ <rect
66
+ key={keyVal(value.id, i)}
67
+ x={fpx(x - barWidthHalf)}
68
+ y={fpy(value.val)}
69
+ width={fpx(barWidth)}
70
+ height={fpx(value.val)}
71
+ fill={value.color}
72
+ />
73
+ );
74
+ }
56
75
  }
57
76
  }
58
- }
59
77
 
60
- return <g>{paths}</g>;
61
- });
78
+ return <g>{paths}</g>;
79
+ }
80
+ );
62
81
 
63
82
  interface SvgBarsHoverProps {
64
83
  onHover(ind: number): void;
@@ -1,6 +1,6 @@
1
1
  import { FC } from 'react';
2
2
  import { observer } from 'mobx-react';
3
- import tokens from '@servicetitan/tokens';
3
+ import { tokens } from '@servicetitan/tokens/core';
4
4
  import { useDependencies } from '@servicetitan/react-ioc';
5
5
 
6
6
  import { SvgStore } from '../stores/svg.store';
@@ -43,6 +43,7 @@ export const SvgBody: FC<SvgBodyProps> = observer(({ horizontalGrid, metrics })
43
43
  const [{ key }] = useDependencies(SvgStore);
44
44
  const barMetrics = metrics.filter(m => m.type === 'bar');
45
45
  const stackedBarMetrics = metrics.filter(m => m.type === 'stacked-bar');
46
+ const groupedBarMetrics = metrics.filter(m => m.type === 'grouped-bar');
46
47
  const lineMetrics = metrics.filter(m => m.type === 'line');
47
48
 
48
49
  return (
@@ -61,6 +62,13 @@ export const SvgBody: FC<SvgBodyProps> = observer(({ horizontalGrid, metrics })
61
62
  isStackedBarChart
62
63
  />
63
64
  )}
65
+ {!!groupedBarMetrics.length && (
66
+ <SvgBars
67
+ key={keyVal('grouped-bars', key)}
68
+ metrics={groupedBarMetrics}
69
+ isGroupedBarChart
70
+ />
71
+ )}
64
72
  {!!lineMetrics.length && <SvgLines key={keyVal('lines', key)} metrics={lineMetrics} />}
65
73
  </svg>
66
74
  );
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .svg-hover {
4
4
  position: absolute;
@@ -154,6 +154,42 @@ export const stackedBarChartDailyBottomTitles = () => {
154
154
  );
155
155
  };
156
156
 
157
+ export const groupedBarChartDailyBottomTitles = () => {
158
+ return (
159
+ <LineChart
160
+ resolution="day"
161
+ metrics={[
162
+ {
163
+ id: 2,
164
+ title: 'Lead Calls',
165
+ type: 'grouped-bar',
166
+ color: '#D0D8DD',
167
+ },
168
+ {
169
+ id: 3,
170
+ title: 'Online Bookings',
171
+ type: 'grouped-bar',
172
+ color: '#08BFDF',
173
+ },
174
+ {
175
+ id: 4,
176
+ title: 'Manual Calls',
177
+ type: 'grouped-bar',
178
+ color: '#1FBC70',
179
+ },
180
+ ]}
181
+ metricValues={stackedBarChartValues.values}
182
+ periods={dailyValues.periods}
183
+ titleY="Left title"
184
+ display={{
185
+ yLeft: false,
186
+ yLeftFormat: 'number',
187
+ metricsTitlePosition: 'bottom',
188
+ }}
189
+ />
190
+ );
191
+ };
192
+
157
193
  export const lineChartWeekly = () => (
158
194
  <LineChart
159
195
  resolution="week"
@@ -21,7 +21,7 @@ const getSideMetricsSettings = (
21
21
  ): SideMetricsSettings | undefined => {
22
22
  let maxRange = range ?? 0;
23
23
  const lineBarMetricIDs = metrics
24
- .filter(m => m.type === 'line' || m.type === 'bar')
24
+ .filter(m => m.type === 'line' || m.type === 'bar' || m.type === 'grouped-bar')
25
25
  .map(m => m.id);
26
26
  const stackedBarMetricIDs = metrics.filter(m => m.type === 'stacked-bar').map(m => m.id);
27
27
 
@@ -29,7 +29,9 @@ export class SvgStore {
29
29
  this.length = length || 1;
30
30
  this.key = Date.now();
31
31
 
32
- const hasBars = !!metrics.filter(m => m.type === 'bar' || m.type === 'stacked-bar').length;
32
+ const hasBars = !!metrics.filter(
33
+ m => m.type === 'bar' || m.type === 'stacked-bar' || m.type === 'grouped-bar'
34
+ ).length;
33
35
 
34
36
  if (hasBars) {
35
37
  this.fullBarWidth = 100 / this.length;
@@ -1,7 +1,7 @@
1
1
  import { ReactElement } from 'react';
2
2
 
3
3
  export type LineChartResolution = 'hour' | 'day' | 'week' | 'month';
4
- export type LineChartMetricType = 'line' | 'bar' | 'stacked-bar';
4
+ export type LineChartMetricType = 'line' | 'bar' | 'stacked-bar' | 'grouped-bar';
5
5
  export type LineChartMetricsTitlePosition = 'top' | 'top-right' | 'bottom';
6
6
 
7
7
  export interface LineChartMetricOpts {
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useMemo, useState, FC, Fragment } from 'react';
2
- import tokens from '@servicetitan/tokens';
2
+ import { tokens } from '@servicetitan/tokens/core';
3
3
  import { BodyText, Popover, Stack, StatusLight } from '@servicetitan/design-system';
4
4
 
5
5
  import { useClientRect } from '../../../../utils/use-client-rect';
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .stat-diff {
4
4
  white-space: nowrap;
@@ -1,4 +1,4 @@
1
- @import (reference) '@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .action-button {
4
4
  color: @color-neutral-80;
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens';
2
2
 
3
3
  /*
4
4
  * Custom value text is not supported for DateRangePicker now (will be implemented in DS-699)
@@ -1,5 +1,5 @@
1
1
  import { BodyText, Icon, Stack, Tooltip } from '@servicetitan/design-system';
2
- import tokens from '@servicetitan/tokens';
2
+ import { tokens } from '@servicetitan/tokens/core';
3
3
  import { FC } from 'react';
4
4
 
5
5
  export interface LabelWithHintProps {
@@ -1,4 +1,4 @@
1
- @import (reference) '~@servicetitan/tokens/dist/tokens';
1
+ @import (reference) '~@servicetitan/tokens/core/tokens';
2
2
 
3
3
  .more-details-wrapper {
4
4
  position: absolute;
@@ -1,4 +1,4 @@
1
- @import (reference) '@servicetitan/tokens/dist/tokens.less';
1
+ @import (reference) '@servicetitan/tokens/core/tokens.less';
2
2
 
3
3
  .popover {
4
4
  padding: @spacing-0;