@servicetitan/marketing-ui 1.11.0 → 1.12.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/index.d.ts CHANGED
@@ -9,4 +9,5 @@ export * from './utils/formatters';
9
9
  export * from './utils/string-case';
10
10
  export * from './utils/use-client-rect';
11
11
  export * from './utils/helpers';
12
+ export * from './utils/format-big-numbers';
12
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0CAA0C,CAAC;AAEzD,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0CAA0C,CAAC;AAEzD,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC"}
package/dist/index.js CHANGED
@@ -21,4 +21,5 @@ __exportStar(require("./utils/formatters"), exports);
21
21
  __exportStar(require("./utils/string-case"), exports);
22
22
  __exportStar(require("./utils/use-client-rect"), exports);
23
23
  __exportStar(require("./utils/helpers"), exports);
24
+ __exportStar(require("./utils/format-big-numbers"), exports);
24
25
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8DAA4C;AAC5C,uEAAqD;AACrD,4DAA0C;AAC1C,mEAAiD;AACjD,4DAA0C;AAC1C,2EAAyD;AAEzD,oDAAkC;AAClC,qDAAmC;AACnC,sDAAoC;AACpC,0DAAwC;AACxC,kDAAgC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8DAA4C;AAC5C,uEAAqD;AACrD,4DAA0C;AAC1C,mEAAiD;AACjD,4DAA0C;AAC1C,2EAAyD;AAEzD,oDAAkC;AAClC,qDAAmC;AACnC,sDAAoC;AACpC,0DAAwC;AACxC,kDAAgC;AAChC,6DAA2C"}
@@ -0,0 +1,2 @@
1
+ export declare const formatBigNumber: (num: number, maximumFractionDigits: number) => string;
2
+ //# sourceMappingURL=format-big-numbers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-big-numbers.d.ts","sourceRoot":"","sources":["../../src/utils/format-big-numbers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,QAAS,MAAM,yBAAyB,MAAM,WAczE,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatBigNumber = void 0;
4
+ const formatBigNumber = (num, maximumFractionDigits) => {
5
+ let formatedNum = num;
6
+ const ranks = ['', 'K', 'M'];
7
+ let rankIndex = 0;
8
+ while (formatedNum > 10000 && rankIndex < ranks.length - 1) {
9
+ formatedNum /= 1000;
10
+ rankIndex++;
11
+ }
12
+ return (formatedNum.toLocaleString(undefined, {
13
+ maximumFractionDigits,
14
+ }) + ranks[rankIndex]);
15
+ };
16
+ exports.formatBigNumber = formatBigNumber;
17
+ //# sourceMappingURL=format-big-numbers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-big-numbers.js","sourceRoot":"","sources":["../../src/utils/format-big-numbers.ts"],"names":[],"mappings":";;;AAAO,MAAM,eAAe,GAAG,CAAC,GAAW,EAAE,qBAA6B,EAAE,EAAE;IAC1E,IAAI,WAAW,GAAG,GAAG,CAAC;IACtB,MAAM,KAAK,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC7B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,WAAW,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;QACxD,WAAW,IAAI,IAAI,CAAC;QACpB,SAAS,EAAE,CAAC;KACf;IAED,OAAO,CACH,WAAW,CAAC,cAAc,CAAC,SAAS,EAAE;QAClC,qBAAqB;KACxB,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CACxB,CAAC;AACN,CAAC,CAAC;AAdW,QAAA,eAAe,mBAc1B"}
@@ -1,2 +1,17 @@
1
1
  export declare const keys: <T extends Record<string, any>>(obj: T) => (keyof T)[];
2
+ /**
3
+ * Searches for words (divided by white space) in the string,
4
+ * i.e `findSubstrIndexes('91203 - Glendale, CA', 'glen 912')`
5
+ * returns `[
6
+ * { start: 0, end: 3 },
7
+ * { start: 8, end: 12 },
8
+ * ]`
9
+ * @param str - String to search in
10
+ * @param substr - Searched words, i.e 'hello world'
11
+ * @returns Array of start and end indexes of the words
12
+ */
13
+ export declare const findSubstrIndexes: (str: string, substr: string) => {
14
+ start: number;
15
+ end: number;
16
+ }[];
2
17
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,wDAA2E,CAAC"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,wDAA2E,CAAC;AAE7F;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,QAAS,MAAM,UAAU,MAAM;;;GA8B5D,CAAC"}
@@ -1,6 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.keys = void 0;
3
+ exports.findSubstrIndexes = exports.keys = void 0;
4
4
  const keys = (obj) => Object.keys(obj);
5
5
  exports.keys = keys;
6
+ /**
7
+ * Searches for words (divided by white space) in the string,
8
+ * i.e `findSubstrIndexes('91203 - Glendale, CA', 'glen 912')`
9
+ * returns `[
10
+ * { start: 0, end: 3 },
11
+ * { start: 8, end: 12 },
12
+ * ]`
13
+ * @param str - String to search in
14
+ * @param substr - Searched words, i.e 'hello world'
15
+ * @returns Array of start and end indexes of the words
16
+ */
17
+ const findSubstrIndexes = (str, substr) => {
18
+ const searchWords = substr.split(' ');
19
+ const realSearchWords = searchWords.filter(word => word !== '');
20
+ const indexes = realSearchWords.map(word => {
21
+ const index = str.toLowerCase().indexOf(word.toLowerCase());
22
+ return {
23
+ start: index,
24
+ end: index + word.length,
25
+ };
26
+ });
27
+ const realIndexes = indexes
28
+ .filter(index => index.start !== -1)
29
+ .sort((indexA, indexB) => indexA.start - indexB.start);
30
+ const realRanges = [];
31
+ if (realIndexes.length >= 1) {
32
+ realRanges.push(realIndexes[0]);
33
+ for (let i = 1; i < realIndexes.length; i++) {
34
+ const lastRealRange = realRanges[realRanges.length - 1];
35
+ if (realIndexes[i].start < lastRealRange.end) {
36
+ lastRealRange.end = realIndexes[i].end;
37
+ }
38
+ else {
39
+ realRanges.push(realIndexes[i]);
40
+ }
41
+ }
42
+ }
43
+ return realRanges;
44
+ };
45
+ exports.findSubstrIndexes = findSubstrIndexes;
6
46
  //# sourceMappingURL=helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":";;;AAAO,MAAM,IAAI,GAAG,CAAgC,GAAM,EAAe,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAAhF,QAAA,IAAI,QAA4E"}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":";;;AAAO,MAAM,IAAI,GAAG,CAAgC,GAAM,EAAe,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAAhF,QAAA,IAAI,QAA4E;AAE7F;;;;;;;;;;GAUG;AACI,MAAM,iBAAiB,GAAG,CAAC,GAAW,EAAE,MAAc,EAAE,EAAE;IAC7D,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACvC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC5D,OAAO;YACH,KAAK,EAAE,KAAK;YACZ,GAAG,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM;SAC3B,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,OAAO;SACtB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;SACnC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE3D,MAAM,UAAU,GAAG,EAAE,CAAC;IAEtB,IAAI,WAAW,CAAC,MAAM,IAAI,CAAC,EAAE;QACzB,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;YACzC,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACxD,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE;gBAC1C,aAAa,CAAC,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;aAC1C;iBAAM;gBACH,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;aACnC;SACJ;KACJ;IAED,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC;AA9BW,QAAA,iBAAiB,qBA8B5B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/marketing-ui",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "description": "Marketing UI component and utils",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,5 +50,5 @@
50
50
  "less": true,
51
51
  "webpack": false
52
52
  },
53
- "gitHead": "9580cd8b8293e38db49599c975164f39af03ba31"
53
+ "gitHead": "67f0c3336d021d6f168f8e9418bfb8811438a654"
54
54
  }
package/src/index.ts CHANGED
@@ -10,3 +10,4 @@ export * from './utils/formatters';
10
10
  export * from './utils/string-case';
11
11
  export * from './utils/use-client-rect';
12
12
  export * from './utils/helpers';
13
+ export * from './utils/format-big-numbers';
@@ -0,0 +1,17 @@
1
+ import { formatBigNumber } from '../format-big-numbers';
2
+
3
+ test('formatBigNumber', () => {
4
+ expect(formatBigNumber(12.333333, 0)).toEqual('12');
5
+ expect(formatBigNumber(12000.333333, 0)).toEqual('12K');
6
+ expect(formatBigNumber(12000000.333333, 0)).toEqual('12M');
7
+ expect(formatBigNumber(12.333333, 2)).toEqual(
8
+ /*
9
+ * I know it's a bad practice to compare like this
10
+ * but I don't want to use preset culture that I get from backend side
11
+ * I want to define culture on the user side
12
+ */
13
+ (12.333333).toLocaleString(undefined, {
14
+ maximumFractionDigits: 2,
15
+ })
16
+ );
17
+ });
@@ -0,0 +1,31 @@
1
+ import { findSubstrIndexes } from '../helpers';
2
+
3
+ describe('[Marketing] helpers', () => {
4
+ test('findSubstrIndexes works well', () => {
5
+ expect(findSubstrIndexes('91203 - Glendale, CA', '912')).toEqual([{ start: 0, end: 3 }]);
6
+ expect(findSubstrIndexes('91203 - Glendale, CA', '912 ')).toEqual([{ start: 0, end: 3 }]);
7
+ expect(findSubstrIndexes('91203 - Glendale, CA', ' 912 ')).toEqual([{ start: 0, end: 3 }]);
8
+ expect(findSubstrIndexes('91203 - Glendale, CA', '912 glen')).toEqual([
9
+ { start: 0, end: 3 },
10
+ { start: 8, end: 12 },
11
+ ]);
12
+ expect(findSubstrIndexes('91203 - Glendale, CA', 'glen 912')).toEqual([
13
+ { start: 0, end: 3 },
14
+ { start: 8, end: 12 },
15
+ ]);
16
+ expect(findSubstrIndexes('91203 - Glendale, CA', 'glen lend 912')).toEqual([
17
+ { start: 0, end: 3 },
18
+ { start: 8, end: 13 },
19
+ ]);
20
+ expect(findSubstrIndexes('91203 - Glendale, CA', 'lend glen 912')).toEqual([
21
+ { start: 0, end: 3 },
22
+ { start: 8, end: 13 },
23
+ ]);
24
+ expect(findSubstrIndexes('91203 - Glendale, CA', 'glen glen 912')).toEqual([
25
+ { start: 0, end: 3 },
26
+ { start: 8, end: 12 },
27
+ ]);
28
+ expect(findSubstrIndexes('91203 - Glendale, CA', '')).toEqual([]);
29
+ expect(findSubstrIndexes('91203 - Glendale, CA', 'blabla')).toEqual([]);
30
+ });
31
+ });
@@ -0,0 +1,15 @@
1
+ export const formatBigNumber = (num: number, maximumFractionDigits: number) => {
2
+ let formatedNum = num;
3
+ const ranks = ['', 'K', 'M'];
4
+ let rankIndex = 0;
5
+ while (formatedNum > 10000 && rankIndex < ranks.length - 1) {
6
+ formatedNum /= 1000;
7
+ rankIndex++;
8
+ }
9
+
10
+ return (
11
+ formatedNum.toLocaleString(undefined, {
12
+ maximumFractionDigits,
13
+ }) + ranks[rankIndex]
14
+ );
15
+ };
@@ -1 +1,44 @@
1
1
  export const keys = <T extends Record<string, any>>(obj: T): (keyof T)[] => Object.keys(obj);
2
+
3
+ /**
4
+ * Searches for words (divided by white space) in the string,
5
+ * i.e `findSubstrIndexes('91203 - Glendale, CA', 'glen 912')`
6
+ * returns `[
7
+ * { start: 0, end: 3 },
8
+ * { start: 8, end: 12 },
9
+ * ]`
10
+ * @param str - String to search in
11
+ * @param substr - Searched words, i.e 'hello world'
12
+ * @returns Array of start and end indexes of the words
13
+ */
14
+ export const findSubstrIndexes = (str: string, substr: string) => {
15
+ const searchWords = substr.split(' ');
16
+ const realSearchWords = searchWords.filter(word => word !== '');
17
+ const indexes = realSearchWords.map(word => {
18
+ const index = str.toLowerCase().indexOf(word.toLowerCase());
19
+ return {
20
+ start: index,
21
+ end: index + word.length,
22
+ };
23
+ });
24
+
25
+ const realIndexes = indexes
26
+ .filter(index => index.start !== -1)
27
+ .sort((indexA, indexB) => indexA.start - indexB.start);
28
+
29
+ const realRanges = [];
30
+
31
+ if (realIndexes.length >= 1) {
32
+ realRanges.push(realIndexes[0]);
33
+ for (let i = 1; i < realIndexes.length; i++) {
34
+ const lastRealRange = realRanges[realRanges.length - 1];
35
+ if (realIndexes[i].start < lastRealRange.end) {
36
+ lastRealRange.end = realIndexes[i].end;
37
+ } else {
38
+ realRanges.push(realIndexes[i]);
39
+ }
40
+ }
41
+ }
42
+
43
+ return realRanges;
44
+ };