@servicetitan/marketing-ui 5.9.0 → 5.10.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.
- package/dist/components/ads/ads-stat.js +21 -10
- package/dist/components/ads/ads-stat.js.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-chart.js +118 -6
- package/dist/components/charts/funnel-chart/components/funnel-chart.js.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-chart.module.less.d.ts +9 -0
- package/dist/components/charts/funnel-chart/components/funnel-svg.js +62 -12
- package/dist/components/charts/funnel-chart/components/funnel-svg.js.map +1 -1
- package/dist/components/charts/funnel-chart/index.js +1 -0
- package/dist/components/charts/funnel-chart/index.js.map +1 -1
- package/dist/components/charts/funnel-chart/utils/const.js +1 -0
- package/dist/components/charts/funnel-chart/utils/const.js.map +1 -1
- package/dist/components/charts/funnel-chart/utils/interface.js +2 -1
- package/dist/components/charts/funnel-chart/utils/interface.js.map +1 -1
- package/dist/components/charts/line-chart/components/body.js +105 -16
- package/dist/components/charts/line-chart/components/body.js.map +1 -1
- package/dist/components/charts/line-chart/components/body.module.less.d.ts +4 -0
- package/dist/components/charts/line-chart/components/container.js +12 -4
- package/dist/components/charts/line-chart/components/container.js.map +1 -1
- package/dist/components/charts/line-chart/components/hover-popover.js +56 -13
- package/dist/components/charts/line-chart/components/hover-popover.js.map +1 -1
- package/dist/components/charts/line-chart/components/hover-popover.module.less.d.ts +5 -0
- package/dist/components/charts/line-chart/components/sidebar.js +35 -5
- package/dist/components/charts/line-chart/components/sidebar.js.map +1 -1
- package/dist/components/charts/line-chart/components/sidebar.module.less.d.ts +13 -0
- package/dist/components/charts/line-chart/components/stuff.js +73 -32
- package/dist/components/charts/line-chart/components/stuff.js.map +1 -1
- package/dist/components/charts/line-chart/components/stuff.module.less.d.ts +6 -0
- package/dist/components/charts/line-chart/components/svg-bars.js +58 -26
- package/dist/components/charts/line-chart/components/svg-bars.js.map +1 -1
- package/dist/components/charts/line-chart/components/svg-body.js +52 -11
- package/dist/components/charts/line-chart/components/svg-body.js.map +1 -1
- package/dist/components/charts/line-chart/components/svg-lines.js +46 -27
- package/dist/components/charts/line-chart/components/svg-lines.js.map +1 -1
- package/dist/components/charts/line-chart/components/svg.module.less.d.ts +5 -0
- package/dist/components/charts/line-chart/index.js +1 -0
- package/dist/components/charts/line-chart/index.js.map +1 -1
- package/dist/components/charts/line-chart/stores/line-chart.store.js +98 -137
- package/dist/components/charts/line-chart/stores/line-chart.store.js.map +1 -1
- package/dist/components/charts/line-chart/stores/svg.store.js +66 -108
- package/dist/components/charts/line-chart/stores/svg.store.js.map +1 -1
- package/dist/components/charts/line-chart/utils/const.js +8 -7
- package/dist/components/charts/line-chart/utils/const.js.map +1 -1
- package/dist/components/charts/line-chart/utils/formatters.js +13 -11
- package/dist/components/charts/line-chart/utils/formatters.js.map +1 -1
- package/dist/components/charts/line-chart/utils/interfaces.js +2 -1
- package/dist/components/charts/line-chart/utils/interfaces.js.map +1 -1
- package/dist/components/charts/line-chart/utils/internal-interfaces.js +2 -1
- package/dist/components/charts/line-chart/utils/internal-interfaces.js.map +1 -1
- package/dist/components/charts/line-chart/utils/key.js +2 -1
- package/dist/components/charts/line-chart/utils/key.js.map +1 -1
- package/dist/components/charts/line-chart/utils/labels.js +50 -46
- package/dist/components/charts/line-chart/utils/labels.js.map +1 -1
- package/dist/components/charts/pie-chart/components/pie-chart.js +60 -6
- package/dist/components/charts/pie-chart/components/pie-chart.js.map +1 -1
- package/dist/components/charts/pie-chart/components/pie-chart.module.less.d.ts +3 -0
- package/dist/components/charts/pie-chart/components/pie.js +176 -39
- package/dist/components/charts/pie-chart/components/pie.js.map +1 -1
- package/dist/components/charts/pie-chart/index.js +2 -0
- package/dist/components/charts/pie-chart/index.js.map +1 -1
- package/dist/components/charts/pie-chart/utils/const.js +55 -39
- package/dist/components/charts/pie-chart/utils/const.js.map +1 -1
- package/dist/components/charts/pie-chart/utils/interface.js +2 -1
- package/dist/components/charts/pie-chart/utils/interface.js.map +1 -1
- package/dist/components/image-cropper/image-cropper.js +74 -88
- package/dist/components/image-cropper/image-cropper.js.map +1 -1
- package/dist/components/stat/stat-card.js +68 -22
- package/dist/components/stat/stat-card.js.map +1 -1
- package/dist/components/stat/stat-card.module.less.d.ts +5 -0
- package/dist/components/stat/stat-extended-card.js +76 -4
- package/dist/components/stat/stat-extended-card.js.map +1 -1
- package/dist/components/ui/action-button/action-button.js +33 -7
- package/dist/components/ui/action-button/action-button.js.map +1 -1
- package/dist/components/ui/action-button/action-button.module.less.d.ts +9 -0
- package/dist/components/ui/action-button/index.js +1 -0
- package/dist/components/ui/action-button/index.js.map +1 -1
- package/dist/components/ui/centered-spinner/centered-spinner.js +20 -2
- package/dist/components/ui/centered-spinner/centered-spinner.js.map +1 -1
- package/dist/components/ui/date-range-picker/date-range-picker.js +71 -35
- package/dist/components/ui/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/ui/date-range-picker/date-range-picker.module.less.d.ts +4 -0
- package/dist/components/ui/disabled-button.js +12 -3
- package/dist/components/ui/disabled-button.js.map +1 -1
- package/dist/components/ui/label-with-hint/label-with-hint.js +23 -1
- package/dist/components/ui/label-with-hint/label-with-hint.js.map +1 -1
- package/dist/components/ui/line-text/index.js +1 -0
- package/dist/components/ui/line-text/index.js.map +1 -1
- package/dist/components/ui/line-text/line-text.js +71 -12
- package/dist/components/ui/line-text/line-text.js.map +1 -1
- package/dist/components/ui/line-text/line-text.module.less.d.ts +6 -0
- package/dist/components/ui/title-popover/index.js +1 -0
- package/dist/components/ui/title-popover/index.js.map +1 -1
- package/dist/components/ui/title-popover/title-popover.js +78 -69
- package/dist/components/ui/title-popover/title-popover.js.map +1 -1
- package/dist/components/ui/title-popover/title-popover.module.less.d.ts +3 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/ads-texts.js +2 -1
- package/dist/utils/ads-texts.js.map +1 -1
- package/dist/utils/date/date-range-picker-options.js +90 -68
- package/dist/utils/date/date-range-picker-options.js.map +1 -1
- package/dist/utils/date/date-range-picker-state.js +42 -43
- package/dist/utils/date/date-range-picker-state.js.map +1 -1
- package/dist/utils/date/date-tenant.js +4 -6
- package/dist/utils/date/date-tenant.js.map +1 -1
- package/dist/utils/date/date.js +5 -9
- package/dist/utils/date/date.js.map +1 -1
- package/dist/utils/date/index.js +1 -0
- package/dist/utils/date/index.js.map +1 -1
- package/dist/utils/format-big-numbers.js +11 -6
- package/dist/utils/format-big-numbers.js.map +1 -1
- package/dist/utils/formatters.js +8 -7
- package/dist/utils/formatters.js.map +1 -1
- package/dist/utils/helpers.js +9 -12
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/marketing-parner-handlers.js +9 -12
- package/dist/utils/marketing-parner-handlers.js.map +1 -1
- package/dist/utils/string-case.js +1 -0
- package/dist/utils/string-case.js.map +1 -1
- package/dist/utils/use-client-rect.js +19 -19
- package/dist/utils/use-client-rect.js.map +1 -1
- package/dist/utils/use-target-range-store.js +7 -6
- package/dist/utils/use-target-range-store.js.map +1 -1
- package/package.json +11 -11
- package/dist/components/charts/funnel-chart/funnel-chart.stories.js +0 -76
- package/dist/components/charts/funnel-chart/funnel-chart.stories.js.map +0 -1
- package/dist/components/charts/line-chart/line-chart.stories.js +0 -225
- package/dist/components/charts/line-chart/line-chart.stories.js.map +0 -1
- package/dist/components/charts/pie-chart/pie-chart.stories.js +0 -22
- package/dist/components/charts/pie-chart/pie-chart.stories.js.map +0 -1
- package/dist/components/image-cropper/image-cropper.stories.js +0 -39
- package/dist/components/image-cropper/image-cropper.stories.js.map +0 -1
- package/dist/components/stat/stat-cards.stories.js +0 -16
- package/dist/components/stat/stat-cards.stories.js.map +0 -1
- package/dist/components/stat/stat-extended-card.stories.js +0 -12
- package/dist/components/stat/stat-extended-card.stories.js.map +0 -1
- package/dist/components/ui/action-button/action-button.stories.js +0 -11
- package/dist/components/ui/action-button/action-button.stories.js.map +0 -1
- package/dist/components/ui/centered-spinner/centered-spinner.stories.js +0 -12
- package/dist/components/ui/centered-spinner/centered-spinner.stories.js.map +0 -1
- package/dist/components/ui/date-range-picker/date-range-picker.stories.js +0 -18
- package/dist/components/ui/date-range-picker/date-range-picker.stories.js.map +0 -1
- package/dist/components/ui/label-with-hint/label-with-hint.stories.js +0 -12
- package/dist/components/ui/label-with-hint/label-with-hint.stories.js.map +0 -1
- package/dist/components/ui/line-text/line-text-body.stories.js +0 -11
- package/dist/components/ui/line-text/line-text-body.stories.js.map +0 -1
- package/dist/components/ui/line-text/line-text-head.stories.js +0 -11
- package/dist/components/ui/line-text/line-text-head.stories.js.map +0 -1
- package/dist/components/ui/title-popover/title-popover.stories.js +0 -17
- package/dist/components/ui/title-popover/title-popover.stories.js.map +0 -1
- package/dist/utils/__tests__/format-big-numbers.test.js +0 -16
- package/dist/utils/__tests__/format-big-numbers.test.js.map +0 -1
- package/dist/utils/__tests__/formatters.test.js +0 -45
- package/dist/utils/__tests__/formatters.test.js.map +0 -1
- package/dist/utils/__tests__/helpers.test.js +0 -31
- package/dist/utils/__tests__/helpers.test.js.map +0 -1
- package/dist/utils/__tests__/string-case.test.js +0 -20
- package/dist/utils/__tests__/string-case.test.js.map +0 -1
- package/dist/utils/date/__mocks__/date-mock.js +0 -19
- package/dist/utils/date/__mocks__/date-mock.js.map +0 -1
- package/dist/utils/date/__tests__/date-range-picker.test.js +0 -93
- package/dist/utils/date/__tests__/date-range-picker.test.js.map +0 -1
- package/dist/utils/date/__tests__/date-tenant.test.js +0 -29
- package/dist/utils/date/__tests__/date-tenant.test.js.map +0 -1
|
@@ -1,44 +1,51 @@
|
|
|
1
|
-
|
|
1
|
+
function _define_property(obj, key, value) {
|
|
2
|
+
if (key in obj) {
|
|
3
|
+
Object.defineProperty(obj, key, {
|
|
4
|
+
value: value,
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true
|
|
8
|
+
});
|
|
9
|
+
} else {
|
|
10
|
+
obj[key] = value;
|
|
11
|
+
}
|
|
12
|
+
return obj;
|
|
13
|
+
}
|
|
14
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
2
15
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
16
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for
|
|
17
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
18
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
}
|
|
7
|
-
|
|
19
|
+
}
|
|
20
|
+
function _ts_metadata(k, v) {
|
|
8
21
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
-
}
|
|
22
|
+
}
|
|
10
23
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
24
|
import { Component } from 'react';
|
|
12
25
|
import { observable, action, makeObservable } from 'mobx';
|
|
13
26
|
import { observer } from 'mobx-react';
|
|
14
|
-
import ReactCrop from 'react-image-crop';
|
|
27
|
+
import ReactCrop, { Crop } from 'react-image-crop';
|
|
15
28
|
import 'react-image-crop/dist/ReactCrop.css';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
37
|
-
Object.defineProperty(this, "getCroppedImg", {
|
|
38
|
-
enumerable: true,
|
|
39
|
-
configurable: true,
|
|
40
|
-
writable: true,
|
|
41
|
-
value: (type, fileName) => new Promise(resolve => {
|
|
29
|
+
export class ImageCropper extends Component {
|
|
30
|
+
componentDidMount() {
|
|
31
|
+
return this.src = URL.createObjectURL(this.props.file);
|
|
32
|
+
}
|
|
33
|
+
componentWillUnmount() {
|
|
34
|
+
if (this.src) {
|
|
35
|
+
URL.revokeObjectURL(this.src);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
render() {
|
|
39
|
+
return this.src ? /*#__PURE__*/ _jsx(ReactCrop, {
|
|
40
|
+
locked: true,
|
|
41
|
+
src: this.src,
|
|
42
|
+
crop: this.crop,
|
|
43
|
+
onChange: this.handleChange,
|
|
44
|
+
onImageLoaded: this.handleImageLoaded
|
|
45
|
+
}) : null;
|
|
46
|
+
}
|
|
47
|
+
constructor(props){
|
|
48
|
+
super(props), _define_property(this, "src", void 0), _define_property(this, "crop", void 0), _define_property(this, "image", void 0), _define_property(this, "getCroppedImg", (type, fileName)=>new Promise((resolve)=>{
|
|
42
49
|
if (!this.image || !this.crop) {
|
|
43
50
|
resolve(undefined);
|
|
44
51
|
return;
|
|
@@ -58,77 +65,56 @@ let ImageCropper = class ImageCropper extends Component {
|
|
|
58
65
|
return;
|
|
59
66
|
}
|
|
60
67
|
ctx.drawImage(this.image, x * (this.image.naturalWidth / this.image.width), y * (this.image.naturalHeight / this.image.height), width, height, 0, 0, width, height);
|
|
61
|
-
canvas.toBlob(blob
|
|
62
|
-
const result = blob ? new File([
|
|
68
|
+
canvas.toBlob((blob)=>{
|
|
69
|
+
const result = blob ? new File([
|
|
70
|
+
blob
|
|
71
|
+
], fileName) : undefined;
|
|
63
72
|
resolve(result);
|
|
64
73
|
}, type, 1);
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
configurable: true,
|
|
76
|
-
writable: true,
|
|
77
|
-
value: (image) => {
|
|
78
|
-
this.image = image;
|
|
79
|
-
this.crop = {
|
|
80
|
-
unit: 'px',
|
|
81
|
-
x: 0,
|
|
82
|
-
y: 0,
|
|
83
|
-
width: this.props.crop.width * (image.width / image.naturalWidth),
|
|
84
|
-
height: this.props.crop.height * (image.height / image.naturalHeight),
|
|
85
|
-
};
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
74
|
+
})), _define_property(this, "handleChange", (crop)=>this.crop = crop), _define_property(this, "handleImageLoaded", (image)=>{
|
|
75
|
+
this.image = image;
|
|
76
|
+
this.crop = {
|
|
77
|
+
unit: 'px',
|
|
78
|
+
x: 0,
|
|
79
|
+
y: 0,
|
|
80
|
+
width: this.props.crop.width * (image.width / image.naturalWidth),
|
|
81
|
+
height: this.props.crop.height * (image.height / image.naturalHeight)
|
|
82
|
+
};
|
|
83
|
+
return false;
|
|
88
84
|
});
|
|
89
85
|
makeObservable(this);
|
|
90
86
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
componentWillUnmount() {
|
|
95
|
-
if (this.src) {
|
|
96
|
-
URL.revokeObjectURL(this.src);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
render() {
|
|
100
|
-
return this.src ? (_jsx(ReactCrop, { locked: true, src: this.src, crop: this.crop, onChange: this.handleChange, onImageLoaded: this.handleImageLoaded })) : null;
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
__decorate([
|
|
87
|
+
}
|
|
88
|
+
_ts_decorate([
|
|
104
89
|
observable,
|
|
105
|
-
|
|
90
|
+
_ts_metadata("design:type", String)
|
|
106
91
|
], ImageCropper.prototype, "src", void 0);
|
|
107
|
-
|
|
92
|
+
_ts_decorate([
|
|
108
93
|
observable,
|
|
109
|
-
|
|
94
|
+
_ts_metadata("design:type", typeof Crop === "undefined" ? Object : Crop)
|
|
110
95
|
], ImageCropper.prototype, "crop", void 0);
|
|
111
|
-
|
|
96
|
+
_ts_decorate([
|
|
112
97
|
observable,
|
|
113
|
-
|
|
98
|
+
_ts_metadata("design:type", typeof HTMLImageElement === "undefined" ? Object : HTMLImageElement)
|
|
114
99
|
], ImageCropper.prototype, "image", void 0);
|
|
115
|
-
|
|
100
|
+
_ts_decorate([
|
|
116
101
|
action,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
102
|
+
_ts_metadata("design:type", Function),
|
|
103
|
+
_ts_metadata("design:paramtypes", []),
|
|
104
|
+
_ts_metadata("design:returntype", void 0)
|
|
120
105
|
], ImageCropper.prototype, "componentDidMount", null);
|
|
121
|
-
|
|
122
|
-
action
|
|
123
|
-
__metadata("design:type", Object)
|
|
106
|
+
_ts_decorate([
|
|
107
|
+
action
|
|
124
108
|
], ImageCropper.prototype, "handleChange", void 0);
|
|
125
|
-
|
|
126
|
-
action
|
|
127
|
-
__metadata("design:type", Object)
|
|
109
|
+
_ts_decorate([
|
|
110
|
+
action
|
|
128
111
|
], ImageCropper.prototype, "handleImageLoaded", void 0);
|
|
129
|
-
ImageCropper =
|
|
112
|
+
ImageCropper = _ts_decorate([
|
|
130
113
|
observer,
|
|
131
|
-
|
|
114
|
+
_ts_metadata("design:type", Function),
|
|
115
|
+
_ts_metadata("design:paramtypes", [
|
|
116
|
+
typeof ImageCropperProps === "undefined" ? Object : ImageCropperProps
|
|
117
|
+
])
|
|
132
118
|
], ImageCropper);
|
|
133
|
-
|
|
119
|
+
|
|
134
120
|
//# sourceMappingURL=image-cropper.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"sources":["../../../src/components/image-cropper/image-cropper.tsx"],"sourcesContent":["import { Component } from 'react';\nimport { observable, action, makeObservable } from 'mobx';\nimport { observer } from 'mobx-react';\nimport ReactCrop, { Crop } from 'react-image-crop';\nimport 'react-image-crop/dist/ReactCrop.css';\n\ninterface ImageCropperProps {\n file: File;\n crop: {\n width: number;\n height: number;\n };\n}\n\n@observer\nexport class ImageCropper extends Component<ImageCropperProps> {\n @observable private src?: string;\n @observable private crop?: Crop;\n @observable private image?: HTMLImageElement;\n\n constructor(props: ImageCropperProps) {\n super(props);\n makeObservable(this);\n }\n\n getCroppedImg = (type: string, fileName: string) =>\n new Promise<File | undefined>(resolve => {\n if (!this.image || !this.crop) {\n resolve(undefined);\n return;\n }\n\n const { x, y } = this.crop;\n if (x == null || y == null) {\n resolve(undefined);\n return;\n }\n\n const { width, height } = this.props.crop;\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n resolve(undefined);\n return;\n }\n\n ctx.drawImage(\n this.image,\n x * (this.image.naturalWidth / this.image.width),\n y * (this.image.naturalHeight / this.image.height),\n width,\n height,\n 0,\n 0,\n width,\n height\n );\n\n canvas.toBlob(\n blob => {\n const result = blob ? new File([blob], fileName) : undefined;\n resolve(result);\n },\n type,\n 1\n );\n });\n\n @action\n componentDidMount() {\n return (this.src = URL.createObjectURL(this.props.file));\n }\n\n componentWillUnmount() {\n if (this.src) {\n URL.revokeObjectURL(this.src);\n }\n }\n\n render() {\n return this.src ? (\n <ReactCrop\n locked\n src={this.src}\n crop={this.crop}\n onChange={this.handleChange}\n onImageLoaded={this.handleImageLoaded}\n />\n ) : null;\n }\n\n @action\n private handleChange = (crop: Crop) => (this.crop = crop);\n\n @action\n private handleImageLoaded = (image: HTMLImageElement) => {\n this.image = image;\n this.crop = {\n unit: 'px',\n x: 0,\n y: 0,\n width: this.props.crop.width * (image.width / image.naturalWidth),\n height: this.props.crop.height * (image.height / image.naturalHeight),\n };\n\n return false;\n };\n}\n"],"names":["Component","observable","action","makeObservable","observer","ReactCrop","Crop","ImageCropper","componentDidMount","src","URL","createObjectURL","props","file","componentWillUnmount","revokeObjectURL","render","locked","crop","onChange","handleChange","onImageLoaded","handleImageLoaded","constructor","image","getCroppedImg","type","fileName","Promise","resolve","undefined","x","y","width","height","canvas","document","createElement","ctx","getContext","drawImage","naturalWidth","naturalHeight","toBlob","blob","result","File","unit"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA,SAASA,SAAS,QAAQ,QAAQ;AAClC,SAASC,UAAU,EAAEC,MAAM,EAAEC,cAAc,QAAQ,OAAO;AAC1D,SAASC,QAAQ,QAAQ,aAAa;AACtC,OAAOC,aAAaC,IAAI,QAAQ,mBAAmB;AACnD,OAAO,sCAAsC;AAW7C,OAAO,MAAMC,qBAAqBP;IAwD9BQ,oBAAoB;QAChB,OAAQ,IAAI,CAACC,GAAG,GAAGC,IAAIC,eAAe,CAAC,IAAI,CAACC,KAAK,CAACC,IAAI;IAC1D;IAEAC,uBAAuB;QACnB,IAAI,IAAI,CAACL,GAAG,EAAE;YACVC,IAAIK,eAAe,CAAC,IAAI,CAACN,GAAG;QAChC;IACJ;IAEAO,SAAS;QACL,OAAO,IAAI,CAACP,GAAG,iBACX,KAACJ;YACGY,MAAM;YACNR,KAAK,IAAI,CAACA,GAAG;YACbS,MAAM,IAAI,CAACA,IAAI;YACfC,UAAU,IAAI,CAACC,YAAY;YAC3BC,eAAe,IAAI,CAACC,iBAAiB;aAEzC;IACR;IAvEAC,YAAYX,KAAwB,CAAE;QAClC,KAAK,CAACA,QALV,uBAAoBH,OAApB,KAAA,IACA,uBAAoBS,QAApB,KAAA,IACA,uBAAoBM,SAApB,KAAA,IAOAC,uBAAAA,iBAAgB,CAACC,MAAcC,WAC3B,IAAIC,QAA0BC,CAAAA;gBAC1B,IAAI,CAAC,IAAI,CAACL,KAAK,IAAI,CAAC,IAAI,CAACN,IAAI,EAAE;oBAC3BW,QAAQC;oBACR;gBACJ;gBAEA,MAAM,EAAEC,CAAC,EAAEC,CAAC,EAAE,GAAG,IAAI,CAACd,IAAI;gBAC1B,IAAIa,KAAK,QAAQC,KAAK,MAAM;oBACxBH,QAAQC;oBACR;gBACJ;gBAEA,MAAM,EAAEG,KAAK,EAAEC,MAAM,EAAE,GAAG,IAAI,CAACtB,KAAK,CAACM,IAAI;gBACzC,MAAMiB,SAASC,SAASC,aAAa,CAAC;gBACtCF,OAAOF,KAAK,GAAGA;gBACfE,OAAOD,MAAM,GAAGA;gBAChB,MAAMI,MAAMH,OAAOI,UAAU,CAAC;gBAC9B,IAAI,CAACD,KAAK;oBACNT,QAAQC;oBACR;gBACJ;gBAEAQ,IAAIE,SAAS,CACT,IAAI,CAAChB,KAAK,EACVO,IAAK,CAAA,IAAI,CAACP,KAAK,CAACiB,YAAY,GAAG,IAAI,CAACjB,KAAK,CAACS,KAAK,AAAD,GAC9CD,IAAK,CAAA,IAAI,CAACR,KAAK,CAACkB,aAAa,GAAG,IAAI,CAAClB,KAAK,CAACU,MAAM,AAAD,GAChDD,OACAC,QACA,GACA,GACAD,OACAC;gBAGJC,OAAOQ,MAAM,CACTC,CAAAA;oBACI,MAAMC,SAASD,OAAO,IAAIE,KAAK;wBAACF;qBAAK,EAAEjB,YAAYG;oBACnDD,QAAQgB;gBACZ,GACAnB,MACA;YAER,KAyBJ,uBACQN,gBAAe,CAACF,OAAgB,IAAI,CAACA,IAAI,GAAGA,OAEpD,uBACQI,qBAAoB,CAACE;YACzB,IAAI,CAACA,KAAK,GAAGA;YACb,IAAI,CAACN,IAAI,GAAG;gBACR6B,MAAM;gBACNhB,GAAG;gBACHC,GAAG;gBACHC,OAAO,IAAI,CAACrB,KAAK,CAACM,IAAI,CAACe,KAAK,GAAIT,CAAAA,MAAMS,KAAK,GAAGT,MAAMiB,YAAY,AAAD;gBAC/DP,QAAQ,IAAI,CAACtB,KAAK,CAACM,IAAI,CAACgB,MAAM,GAAIV,CAAAA,MAAMU,MAAM,GAAGV,MAAMkB,aAAa,AAAD;YACvE;YAEA,OAAO;QACX;QAtFIvC,eAAe,IAAI;IACvB;AAsFJ"}
|
|
@@ -1,66 +1,112 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
|
-
import { BodyText, Eyebrow, Popover, Stack, Tooltip
|
|
4
|
+
import { BodyText, Eyebrow, Popover, Stack, Tooltip } from '@servicetitan/design-system';
|
|
5
5
|
import * as Styles from './stat-card.module.less';
|
|
6
6
|
import { formatValue } from '../../utils/formatters';
|
|
7
|
-
const calculateDiff = (value, prev, percents)
|
|
7
|
+
const calculateDiff = (value, prev, percents)=>{
|
|
8
8
|
const diff = (value - prev) * (percents ? 100 : 1);
|
|
9
9
|
const absDiff = Math.abs(diff);
|
|
10
10
|
let diffPercent = 0;
|
|
11
11
|
if (percents) {
|
|
12
12
|
diffPercent = diff;
|
|
13
|
+
} else if (absDiff) {
|
|
14
|
+
diffPercent = prev ? 100 * absDiff / prev : 100;
|
|
13
15
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
return [
|
|
17
|
+
absDiff,
|
|
18
|
+
diffPercent,
|
|
19
|
+
diff >= 0
|
|
20
|
+
];
|
|
18
21
|
};
|
|
19
|
-
const formatDifference = (value, isPlus, format)
|
|
22
|
+
const formatDifference = (value, isPlus, format)=>{
|
|
20
23
|
return (isPlus ? '+' : '-') + formatValue(value, format);
|
|
21
24
|
};
|
|
22
|
-
const formatDifferencePercentage = (value, isPlus)
|
|
25
|
+
const formatDifferencePercentage = (value, isPlus)=>{
|
|
23
26
|
if (!value) {
|
|
24
27
|
return '';
|
|
25
28
|
}
|
|
26
29
|
return (isPlus ? '+' : '-') + formatValue(value, 'percent-100');
|
|
27
30
|
};
|
|
28
|
-
export const StatDiff = ({ value, prev, size, format, inverted, neutral, className, diffPercentOnly = false
|
|
31
|
+
export const StatDiff = ({ value, prev, size, format, inverted, neutral, className, diffPercentOnly = false })=>{
|
|
29
32
|
const percents = format === 'percent';
|
|
30
33
|
const [absDiff, diffPercent, isIncrease] = calculateDiff(value !== null && value !== void 0 ? value : 0, prev !== null && prev !== void 0 ? prev : 0, percents);
|
|
31
34
|
const diff = absDiff === 0 ? '' : isIncrease ? '▲ ' : '▼ ';
|
|
32
35
|
let text = '';
|
|
33
36
|
if (percents) {
|
|
34
37
|
text += formatDifferencePercentage(absDiff, isIncrease);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
38
|
+
} else {
|
|
37
39
|
const diffPercentage = formatDifferencePercentage(diffPercent, isIncrease);
|
|
38
40
|
if (diffPercentOnly) {
|
|
39
41
|
text += `${diffPercentage}`;
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
+
} else {
|
|
42
43
|
text += `${formatDifference(absDiff, isIncrease, format)}`;
|
|
43
44
|
if (diffPercent !== 0) {
|
|
44
45
|
text += ` (${diffPercentage})`;
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
return
|
|
49
|
+
return /*#__PURE__*/ _jsxs(BodyText, {
|
|
50
|
+
className: classNames(Styles.statDiff, {
|
|
49
51
|
'c-red-500': !neutral && (inverted ? isIncrease : !isIncrease),
|
|
50
52
|
'c-green-500': !neutral && (inverted ? !isIncrease : isIncrease),
|
|
51
|
-
'c-neutral-200': !!neutral
|
|
52
|
-
}, className),
|
|
53
|
+
'c-neutral-200': !!neutral
|
|
54
|
+
}, className),
|
|
55
|
+
size: size !== null && size !== void 0 ? size : 'small',
|
|
56
|
+
"data-cy": "stat-diff-value",
|
|
57
|
+
children: [
|
|
58
|
+
/*#__PURE__*/ _jsx("span", {
|
|
59
|
+
children: diff
|
|
60
|
+
}),
|
|
61
|
+
value === undefined ? '\u00A0' : text
|
|
62
|
+
]
|
|
63
|
+
});
|
|
53
64
|
};
|
|
54
|
-
export const StatCard = ({ title, description, popoverContent, value, percent, money, rate, prev, clean, inverted, neutral, fill, valueOnly, className, diffPercentOnly = false
|
|
65
|
+
export const StatCard = ({ title, description, popoverContent, value, percent, money, rate, prev, clean, inverted, neutral, fill, valueOnly, className, diffPercentOnly = false })=>{
|
|
55
66
|
const [popoverShown, setPopoverShown] = useState(false);
|
|
56
67
|
const format = money ? 'money' : percent ? 'percent' : rate ? 'rate' : 'number';
|
|
57
68
|
const val = value === undefined ? '\u00A0' : formatValue(value, format);
|
|
58
|
-
const eyebrow =
|
|
69
|
+
const eyebrow = /*#__PURE__*/ _jsx(Eyebrow, {
|
|
70
|
+
className: classNames(Styles.title, 'ta-center'),
|
|
71
|
+
"data-cy": `marketing-stat-${title}-title`,
|
|
72
|
+
onMouseEnter: ()=>{
|
|
59
73
|
setPopoverShown(true);
|
|
60
|
-
},
|
|
61
|
-
|
|
74
|
+
},
|
|
75
|
+
children: title
|
|
76
|
+
});
|
|
77
|
+
return /*#__PURE__*/ _jsxs(Stack, {
|
|
78
|
+
direction: "column",
|
|
79
|
+
alignItems: "center",
|
|
80
|
+
className: classNames('p-y-3', {
|
|
62
81
|
'bg-white border-radius-2 border': !clean,
|
|
63
|
-
'flex-grow-1 flex-basis-0': fill
|
|
64
|
-
}, className),
|
|
82
|
+
'flex-grow-1 flex-basis-0': fill
|
|
83
|
+
}, className),
|
|
84
|
+
onMouseLeave: ()=>setPopoverShown(false),
|
|
85
|
+
children: [
|
|
86
|
+
popoverContent ? /*#__PURE__*/ _jsx(Popover, {
|
|
87
|
+
open: popoverShown,
|
|
88
|
+
trigger: eyebrow,
|
|
89
|
+
children: popoverContent
|
|
90
|
+
}) : description ? /*#__PURE__*/ _jsx(Tooltip, {
|
|
91
|
+
text: description,
|
|
92
|
+
"data-cy": `marketing-stat-${title}-tooltip`,
|
|
93
|
+
children: eyebrow
|
|
94
|
+
}) : eyebrow,
|
|
95
|
+
/*#__PURE__*/ _jsx(BodyText, {
|
|
96
|
+
className: "fs-6-i ff-display",
|
|
97
|
+
"data-cy": `marketing-stat-${title}-value`,
|
|
98
|
+
children: val
|
|
99
|
+
}),
|
|
100
|
+
!valueOnly && /*#__PURE__*/ _jsx(StatDiff, {
|
|
101
|
+
value: value,
|
|
102
|
+
prev: prev,
|
|
103
|
+
format: format,
|
|
104
|
+
inverted: inverted,
|
|
105
|
+
neutral: neutral,
|
|
106
|
+
diffPercentOnly: diffPercentOnly
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
});
|
|
65
110
|
};
|
|
111
|
+
|
|
66
112
|
//# sourceMappingURL=stat-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"sources":["../../../src/components/stat/stat-card.tsx"],"sourcesContent":["import { FC, ReactNode, useState } from 'react';\nimport classNames from 'classnames';\nimport {\n BodyText,\n BodyTextPropsStrict,\n Eyebrow,\n Popover,\n Stack,\n Tooltip,\n} from '@servicetitan/design-system';\nimport * as Styles from './stat-card.module.less';\nimport { formatValue, NumberFormatter } from '../../utils/formatters';\n\nconst calculateDiff = (\n value: number,\n prev: number,\n percents?: boolean\n): [number, number, boolean] => {\n const diff = (value - prev) * (percents ? 100 : 1);\n const absDiff = Math.abs(diff);\n let diffPercent = 0;\n\n if (percents) {\n diffPercent = diff;\n } else if (absDiff) {\n diffPercent = prev ? (100 * absDiff) / prev : 100;\n }\n\n return [absDiff, diffPercent, diff >= 0];\n};\n\nconst formatDifference = (value: number, isPlus: boolean, format: NumberFormatter): string => {\n return (isPlus ? '+' : '-') + formatValue(value, format);\n};\n\nconst formatDifferencePercentage = (value: number, isPlus: boolean): string => {\n if (!value) {\n return '';\n }\n\n return (isPlus ? '+' : '-') + formatValue(value, 'percent-100');\n};\n\ninterface StatDiffProps {\n value?: number;\n prev?: number;\n size?: BodyTextPropsStrict['size'];\n format: NumberFormatter;\n inverted?: boolean;\n neutral?: boolean;\n className?: string;\n diffPercentOnly?: boolean;\n}\n\nexport const StatDiff: FC<StatDiffProps> = ({\n value,\n prev,\n size,\n format,\n inverted,\n neutral,\n className,\n diffPercentOnly = false,\n}) => {\n const percents = format === 'percent';\n const [absDiff, diffPercent, isIncrease] = calculateDiff(value ?? 0, prev ?? 0, percents);\n const diff = absDiff === 0 ? '' : isIncrease ? '▲ ' : '▼ ';\n let text = '';\n\n if (percents) {\n text += formatDifferencePercentage(absDiff, isIncrease);\n } else {\n const diffPercentage = formatDifferencePercentage(diffPercent, isIncrease);\n\n if (diffPercentOnly) {\n text += `${diffPercentage}`;\n } else {\n text += `${formatDifference(absDiff, isIncrease, format)}`;\n\n if (diffPercent !== 0) {\n text += ` (${diffPercentage})`;\n }\n }\n }\n\n return (\n <BodyText\n className={classNames(\n Styles.statDiff,\n {\n 'c-red-500': !neutral && (inverted ? isIncrease : !isIncrease),\n 'c-green-500': !neutral && (inverted ? !isIncrease : isIncrease),\n 'c-neutral-200': !!neutral,\n },\n className\n )}\n size={size ?? 'small'}\n data-cy=\"stat-diff-value\"\n >\n <span>{diff}</span>\n {value === undefined ? '\\u00A0' : text}\n </BodyText>\n );\n};\n\nexport interface StatCardProps {\n title: string;\n description?: string;\n popoverContent?: ReactNode;\n value?: number;\n prev?: number;\n percent?: boolean;\n money?: boolean;\n rate?: boolean;\n clean?: boolean;\n inverted?: boolean;\n neutral?: boolean;\n fill?: boolean;\n valueOnly?: boolean;\n className?: string;\n diffPercentOnly?: boolean;\n}\n\nexport const StatCard: FC<StatCardProps> = ({\n title,\n description,\n popoverContent,\n value,\n percent,\n money,\n rate,\n prev,\n clean,\n inverted,\n neutral,\n fill,\n valueOnly,\n className,\n diffPercentOnly = false,\n}) => {\n const [popoverShown, setPopoverShown] = useState(false);\n const format = money ? 'money' : percent ? 'percent' : rate ? 'rate' : 'number';\n const val = value === undefined ? '\\u00A0' : formatValue(value, format);\n\n const eyebrow = (\n <Eyebrow\n className={classNames(Styles.title, 'ta-center')}\n data-cy={`marketing-stat-${title}-title`}\n onMouseEnter={() => {\n setPopoverShown(true);\n }}\n >\n {title}\n </Eyebrow>\n );\n\n return (\n <Stack\n direction=\"column\"\n alignItems=\"center\"\n className={classNames(\n 'p-y-3',\n {\n 'bg-white border-radius-2 border': !clean,\n 'flex-grow-1 flex-basis-0': fill,\n },\n className\n )}\n onMouseLeave={() => setPopoverShown(false)}\n >\n {popoverContent ? (\n <Popover open={popoverShown} trigger={eyebrow}>\n {popoverContent}\n </Popover>\n ) : description ? (\n <Tooltip text={description} data-cy={`marketing-stat-${title}-tooltip`}>\n {eyebrow}\n </Tooltip>\n ) : (\n eyebrow\n )}\n <BodyText className=\"fs-6-i ff-display\" data-cy={`marketing-stat-${title}-value`}>\n {val}\n </BodyText>\n {!valueOnly && (\n <StatDiff\n value={value}\n prev={prev}\n format={format}\n inverted={inverted}\n neutral={neutral}\n diffPercentOnly={diffPercentOnly}\n />\n )}\n </Stack>\n );\n};\n"],"names":["useState","classNames","BodyText","Eyebrow","Popover","Stack","Tooltip","Styles","formatValue","calculateDiff","value","prev","percents","diff","absDiff","Math","abs","diffPercent","formatDifference","isPlus","format","formatDifferencePercentage","StatDiff","size","inverted","neutral","className","diffPercentOnly","isIncrease","text","diffPercentage","statDiff","data-cy","span","undefined","StatCard","title","description","popoverContent","percent","money","rate","clean","fill","valueOnly","popoverShown","setPopoverShown","val","eyebrow","onMouseEnter","direction","alignItems","onMouseLeave","open","trigger"],"mappings":"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"}
|
|
@@ -4,10 +4,82 @@ import { BodyText, Icon, Headline, Eyebrow, Stack, Tooltip } from '@servicetitan
|
|
|
4
4
|
import { formatValue } from '../../utils/formatters';
|
|
5
5
|
import { StatDiff } from './stat-card';
|
|
6
6
|
import * as Styles from './stat-card.module.less';
|
|
7
|
-
export const StatExtendedCard = ({ title, title2, description, value, goal, prev, percent, money, rate, inverted, neutral, fill, className, actions
|
|
7
|
+
export const StatExtendedCard = ({ title, title2, description, value, goal, prev, percent, money, rate, inverted, neutral, fill, className, actions })=>{
|
|
8
8
|
const format = money ? 'money' : percent ? 'percent' : rate ? 'rate' : 'number';
|
|
9
|
-
return
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
10
|
+
className: classNames('p-3 bg-white border border-radius-2', {
|
|
11
|
+
'flex-grow-1 flex-basis-0': fill
|
|
12
|
+
}, className),
|
|
13
|
+
children: [
|
|
14
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
15
|
+
justifyContent: "space-between",
|
|
16
|
+
alignItems: "center",
|
|
17
|
+
children: [
|
|
18
|
+
/*#__PURE__*/ _jsx(Stack.Item, {
|
|
19
|
+
fill: true,
|
|
20
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
21
|
+
children: [
|
|
22
|
+
/*#__PURE__*/ _jsx(Headline, {
|
|
23
|
+
size: "small",
|
|
24
|
+
children: title
|
|
25
|
+
}),
|
|
26
|
+
!!description && /*#__PURE__*/ _jsx(Tooltip, {
|
|
27
|
+
text: description,
|
|
28
|
+
"data-cy": `marketing-stat-card-${title}-info-tooltip`,
|
|
29
|
+
children: /*#__PURE__*/ _jsx(Icon, {
|
|
30
|
+
name: "info",
|
|
31
|
+
size: 18,
|
|
32
|
+
className: "c-neutral-80 m-l-half",
|
|
33
|
+
"data-cy": `marketing-stat-card-${title}-info-icon`
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
]
|
|
37
|
+
})
|
|
38
|
+
}),
|
|
39
|
+
actions && /*#__PURE__*/ _jsx(Stack.Item, {
|
|
40
|
+
shrink: 0,
|
|
41
|
+
children: actions
|
|
42
|
+
})
|
|
43
|
+
]
|
|
44
|
+
}),
|
|
45
|
+
/*#__PURE__*/ _jsx(Eyebrow, {
|
|
46
|
+
size: "small",
|
|
47
|
+
className: "m-t-2 c-black",
|
|
48
|
+
"data-cy": `marketing-stat-card-${title2}-title2`,
|
|
49
|
+
children: title2
|
|
50
|
+
}),
|
|
51
|
+
/*#__PURE__*/ _jsx(Stack, {
|
|
52
|
+
justifyContent: "space-between",
|
|
53
|
+
className: "m-t-half",
|
|
54
|
+
children: /*#__PURE__*/ _jsxs(Stack, {
|
|
55
|
+
alignItems: "flex-end",
|
|
56
|
+
className: "flex-grow-1 flex-basis-0",
|
|
57
|
+
children: [
|
|
58
|
+
/*#__PURE__*/ _jsx(Headline, {
|
|
59
|
+
className: "m-b-0-i m-r-half fw-normal-i",
|
|
60
|
+
size: "xlarge",
|
|
61
|
+
children: formatValue(value, format)
|
|
62
|
+
}),
|
|
63
|
+
goal !== undefined ? /*#__PURE__*/ _jsxs(BodyText, {
|
|
64
|
+
subdued: true,
|
|
65
|
+
children: [
|
|
66
|
+
"/ ",
|
|
67
|
+
formatValue(goal, format),
|
|
68
|
+
" (Goal)"
|
|
69
|
+
]
|
|
70
|
+
}) : prev !== undefined ? /*#__PURE__*/ _jsx(StatDiff, {
|
|
71
|
+
value: value,
|
|
72
|
+
prev: prev,
|
|
73
|
+
format: format,
|
|
74
|
+
inverted: inverted,
|
|
75
|
+
neutral: neutral,
|
|
76
|
+
className: classNames(Styles.statExtendedDiff, 'm-l-1')
|
|
77
|
+
}) : undefined
|
|
78
|
+
]
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
]
|
|
82
|
+
});
|
|
12
83
|
};
|
|
84
|
+
|
|
13
85
|
//# sourceMappingURL=stat-extended-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"sources":["../../../src/components/stat/stat-extended-card.tsx"],"sourcesContent":["import { FC, ReactNode } from 'react';\nimport classNames from 'classnames';\nimport { BodyText, Icon, Headline, Eyebrow, Stack, Tooltip } from '@servicetitan/design-system';\nimport { formatValue } from '../../utils/formatters';\nimport { StatDiff } from './stat-card';\nimport * as Styles from './stat-card.module.less';\n\nexport interface StatExtendedCardProps {\n title: string;\n description?: string;\n title2: string;\n value: number;\n goal?: number;\n prev?: number;\n percent?: boolean;\n money?: boolean;\n rate?: boolean;\n inverted?: boolean;\n neutral?: boolean;\n fill?: boolean;\n className?: string;\n actions?: ReactNode;\n}\nexport const StatExtendedCard: FC<StatExtendedCardProps> = ({\n title,\n title2,\n description,\n value,\n goal,\n prev,\n percent,\n money,\n rate,\n inverted,\n neutral,\n fill,\n className,\n actions,\n}) => {\n const format = money ? 'money' : percent ? 'percent' : rate ? 'rate' : 'number';\n\n return (\n <div\n className={classNames(\n 'p-3 bg-white border border-radius-2',\n {\n 'flex-grow-1 flex-basis-0': fill,\n },\n className\n )}\n >\n <Stack justifyContent=\"space-between\" alignItems=\"center\">\n <Stack.Item fill>\n <Stack>\n <Headline size=\"small\">{title}</Headline>\n {!!description && (\n <Tooltip\n text={description}\n data-cy={`marketing-stat-card-${title}-info-tooltip`}\n >\n <Icon\n name=\"info\"\n size={18}\n className=\"c-neutral-80 m-l-half\"\n data-cy={`marketing-stat-card-${title}-info-icon`}\n />\n </Tooltip>\n )}\n </Stack>\n </Stack.Item>\n {actions && <Stack.Item shrink={0}>{actions}</Stack.Item>}\n </Stack>\n <Eyebrow\n size=\"small\"\n className=\"m-t-2 c-black\"\n data-cy={`marketing-stat-card-${title2}-title2`}\n >\n {title2}\n </Eyebrow>\n\n <Stack justifyContent=\"space-between\" className=\"m-t-half\">\n <Stack alignItems=\"flex-end\" className=\"flex-grow-1 flex-basis-0\">\n <Headline className=\"m-b-0-i m-r-half fw-normal-i\" size=\"xlarge\">\n {formatValue(value, format)}\n </Headline>\n {goal !== undefined ? (\n <BodyText subdued>/ {formatValue(goal, format)} (Goal)</BodyText>\n ) : prev !== undefined ? (\n <StatDiff\n value={value}\n prev={prev}\n format={format}\n inverted={inverted}\n neutral={neutral}\n className={classNames(Styles.statExtendedDiff, 'm-l-1')}\n />\n ) : undefined}\n </Stack>\n </Stack>\n </div>\n );\n};\n"],"names":["classNames","BodyText","Icon","Headline","Eyebrow","Stack","Tooltip","formatValue","StatDiff","Styles","StatExtendedCard","title","title2","description","value","goal","prev","percent","money","rate","inverted","neutral","fill","className","actions","format","div","justifyContent","alignItems","Item","size","text","data-cy","name","shrink","undefined","subdued","statExtendedDiff"],"mappings":";AACA,OAAOA,gBAAgB,aAAa;AACpC,SAASC,QAAQ,EAAEC,IAAI,EAAEC,QAAQ,EAAEC,OAAO,EAAEC,KAAK,EAAEC,OAAO,QAAQ,8BAA8B;AAChG,SAASC,WAAW,QAAQ,yBAAyB;AACrD,SAASC,QAAQ,QAAQ,cAAc;AACvC,YAAYC,YAAY,0BAA0B;AAkBlD,OAAO,MAAMC,mBAA8C,CAAC,EACxDC,KAAK,EACLC,MAAM,EACNC,WAAW,EACXC,KAAK,EACLC,IAAI,EACJC,IAAI,EACJC,OAAO,EACPC,KAAK,EACLC,IAAI,EACJC,QAAQ,EACRC,OAAO,EACPC,IAAI,EACJC,SAAS,EACTC,OAAO,EACV;IACG,MAAMC,SAASP,QAAQ,UAAUD,UAAU,YAAYE,OAAO,SAAS;IAEvE,qBACI,MAACO;QACGH,WAAWvB,WACP,uCACA;YACI,4BAA4BsB;QAChC,GACAC;;0BAGJ,MAAClB;gBAAMsB,gBAAe;gBAAgBC,YAAW;;kCAC7C,KAACvB,MAAMwB,IAAI;wBAACP,IAAI;kCACZ,cAAA,MAACjB;;8CACG,KAACF;oCAAS2B,MAAK;8CAASnB;;gCACvB,CAAC,CAACE,6BACC,KAACP;oCACGyB,MAAMlB;oCACNmB,WAAS,CAAC,oBAAoB,EAAErB,MAAM,aAAa,CAAC;8CAEpD,cAAA,KAACT;wCACG+B,MAAK;wCACLH,MAAM;wCACNP,WAAU;wCACVS,WAAS,CAAC,oBAAoB,EAAErB,MAAM,UAAU,CAAC;;;;;;oBAMpEa,yBAAW,KAACnB,MAAMwB,IAAI;wBAACK,QAAQ;kCAAIV;;;;0BAExC,KAACpB;gBACG0B,MAAK;gBACLP,WAAU;gBACVS,WAAS,CAAC,oBAAoB,EAAEpB,OAAO,OAAO,CAAC;0BAE9CA;;0BAGL,KAACP;gBAAMsB,gBAAe;gBAAgBJ,WAAU;0BAC5C,cAAA,MAAClB;oBAAMuB,YAAW;oBAAWL,WAAU;;sCACnC,KAACpB;4BAASoB,WAAU;4BAA+BO,MAAK;sCACnDvB,YAAYO,OAAOW;;wBAEvBV,SAASoB,0BACN,MAAClC;4BAASmC,OAAO;;gCAAC;gCAAG7B,YAAYQ,MAAMU;gCAAQ;;6BAC/CT,SAASmB,0BACT,KAAC3B;4BACGM,OAAOA;4BACPE,MAAMA;4BACNS,QAAQA;4BACRL,UAAUA;4BACVC,SAASA;4BACTE,WAAWvB,WAAWS,OAAO4B,gBAAgB,EAAE;6BAEnDF;;;;;;AAKxB,EAAE"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useRef } from 'react';
|
|
3
3
|
import classnames from 'classnames';
|
|
4
|
-
import { Icon, BodyText, Tooltip, useFocusVisible
|
|
4
|
+
import { Icon, BodyText, Tooltip, useFocusVisible } from '@servicetitan/design-system';
|
|
5
5
|
import * as Styles from './action-button.module.less';
|
|
6
|
-
export const ActionButton = ({ onClick, disabled, children, iconName, hover, qaPrefix, active, tooltip
|
|
6
|
+
export const ActionButton = ({ onClick, disabled, children, iconName, hover, qaPrefix, active, tooltip })=>{
|
|
7
7
|
const buttonRef = useRef(null);
|
|
8
8
|
const { isFocusVisible, focusFunction, blurFunction } = useFocusVisible(buttonRef);
|
|
9
|
-
const handleClick = ()
|
|
9
|
+
const handleClick = ()=>{
|
|
10
10
|
if (disabled) {
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
@@ -14,19 +14,45 @@ export const ActionButton = ({ onClick, disabled, children, iconName, hover, qaP
|
|
|
14
14
|
onClick();
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
|
-
const getButton = ()
|
|
17
|
+
const getButton = ()=>{
|
|
18
18
|
const classes = classnames(Styles.actionButton, qaPrefix, {
|
|
19
19
|
[Styles.primary]: hover === 'primary' && !disabled,
|
|
20
20
|
[Styles.negative]: hover === 'negative' && !disabled,
|
|
21
21
|
[Styles.active]: active && !disabled,
|
|
22
22
|
[Styles.disabled]: disabled,
|
|
23
|
-
[Styles.focusVisible]: isFocusVisible
|
|
23
|
+
[Styles.focusVisible]: isFocusVisible
|
|
24
|
+
});
|
|
25
|
+
return /*#__PURE__*/ _jsxs("button", {
|
|
26
|
+
type: "button",
|
|
27
|
+
ref: buttonRef,
|
|
28
|
+
className: classes,
|
|
29
|
+
onClick: handleClick,
|
|
30
|
+
disabled: disabled,
|
|
31
|
+
onFocus: focusFunction,
|
|
32
|
+
onBlur: blurFunction,
|
|
33
|
+
children: [
|
|
34
|
+
iconName && /*#__PURE__*/ _jsx(Icon, {
|
|
35
|
+
name: iconName,
|
|
36
|
+
size: "20px",
|
|
37
|
+
className: "m-r-1"
|
|
38
|
+
}),
|
|
39
|
+
/*#__PURE__*/ _jsx(BodyText, {
|
|
40
|
+
className: classnames(Styles.text, `${qaPrefix}-text`),
|
|
41
|
+
children: children
|
|
42
|
+
})
|
|
43
|
+
]
|
|
24
44
|
});
|
|
25
|
-
return (_jsxs("button", { type: "button", ref: buttonRef, className: classes, onClick: handleClick, disabled: disabled, onFocus: focusFunction, onBlur: blurFunction, children: [iconName && _jsx(Icon, { name: iconName, size: "20px", className: "m-r-1" }), _jsx(BodyText, { className: classnames(Styles.text, `${qaPrefix}-text`), children: children })] }));
|
|
26
45
|
};
|
|
27
46
|
if (!tooltip) {
|
|
28
47
|
return getButton();
|
|
29
48
|
}
|
|
30
|
-
return
|
|
49
|
+
return /*#__PURE__*/ _jsx(Tooltip, {
|
|
50
|
+
text: tooltip,
|
|
51
|
+
direction: "l",
|
|
52
|
+
el: "div",
|
|
53
|
+
className: `${qaPrefix}-tooltip`,
|
|
54
|
+
children: getButton()
|
|
55
|
+
});
|
|
31
56
|
};
|
|
57
|
+
|
|
32
58
|
//# sourceMappingURL=action-button.js.map
|