@servicetitan/marketing-ui 1.8.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/components/ads/ads-stat.d.ts +3 -3
- package/dist/components/ads/ads-stat.d.ts.map +1 -1
- package/dist/components/ads/ads-stat.js.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-chart.d.ts +2 -2
- package/dist/components/charts/funnel-chart/components/funnel-chart.d.ts.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-chart.js.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-svg.d.ts +2 -2
- package/dist/components/charts/funnel-chart/components/funnel-svg.d.ts.map +1 -1
- package/dist/components/charts/funnel-chart/components/funnel-svg.js.map +1 -1
- package/dist/components/charts/funnel-chart/funnel-chart.stories.d.ts +2 -2
- package/dist/components/charts/funnel-chart/funnel-chart.stories.d.ts.map +1 -1
- package/dist/components/charts/funnel-chart/funnel-chart.stories.js.map +1 -1
- package/dist/components/charts/line-chart/components/body.d.ts +2 -2
- package/dist/components/charts/line-chart/components/body.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/body.js +2 -2
- package/dist/components/charts/line-chart/components/body.js.map +1 -1
- package/dist/components/charts/line-chart/components/container.d.ts +2 -2
- package/dist/components/charts/line-chart/components/container.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/container.js.map +1 -1
- package/dist/components/charts/line-chart/components/hover-popover.d.ts +2 -2
- package/dist/components/charts/line-chart/components/hover-popover.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/hover-popover.js +2 -2
- package/dist/components/charts/line-chart/components/hover-popover.js.map +1 -1
- package/dist/components/charts/line-chart/components/sidebar.d.ts +2 -2
- package/dist/components/charts/line-chart/components/sidebar.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/sidebar.js.map +1 -1
- package/dist/components/charts/line-chart/components/stuff.d.ts +4 -4
- package/dist/components/charts/line-chart/components/stuff.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/stuff.js.map +1 -1
- package/dist/components/charts/line-chart/components/svg-bars.d.ts +3 -3
- package/dist/components/charts/line-chart/components/svg-bars.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/svg-bars.js.map +1 -1
- package/dist/components/charts/line-chart/components/svg-body.d.ts +3 -3
- package/dist/components/charts/line-chart/components/svg-body.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/svg-body.js.map +1 -1
- package/dist/components/charts/line-chart/components/svg-lines.d.ts +2 -2
- package/dist/components/charts/line-chart/components/svg-lines.d.ts.map +1 -1
- package/dist/components/charts/line-chart/components/svg-lines.js.map +1 -1
- package/dist/components/charts/line-chart/line-chart.stories.d.ts +2 -2
- package/dist/components/charts/line-chart/line-chart.stories.d.ts.map +1 -1
- package/dist/components/charts/line-chart/line-chart.stories.js.map +1 -1
- package/dist/components/charts/line-chart/utils/interfaces.d.ts +2 -2
- package/dist/components/charts/line-chart/utils/interfaces.d.ts.map +1 -1
- package/dist/components/charts/pie-chart/components/pie-chart.d.ts +2 -2
- package/dist/components/charts/pie-chart/components/pie-chart.d.ts.map +1 -1
- package/dist/components/charts/pie-chart/components/pie-chart.js +3 -3
- package/dist/components/charts/pie-chart/components/pie-chart.js.map +1 -1
- package/dist/components/charts/pie-chart/components/pie.d.ts +5 -2
- package/dist/components/charts/pie-chart/components/pie.d.ts.map +1 -1
- package/dist/components/charts/pie-chart/components/pie.js +12 -32
- package/dist/components/charts/pie-chart/components/pie.js.map +1 -1
- package/dist/components/charts/pie-chart/pie-chart.stories.d.ts +3 -2
- package/dist/components/charts/pie-chart/pie-chart.stories.d.ts.map +1 -1
- package/dist/components/charts/pie-chart/pie-chart.stories.js +7 -1
- package/dist/components/charts/pie-chart/pie-chart.stories.js.map +1 -1
- package/dist/components/charts/pie-chart/utils/const.d.ts +2 -2
- package/dist/components/charts/pie-chart/utils/const.d.ts.map +1 -1
- package/dist/components/charts/pie-chart/utils/const.js +9 -7
- package/dist/components/charts/pie-chart/utils/const.js.map +1 -1
- package/dist/components/charts/pie-chart/utils/interface.d.ts +5 -2
- package/dist/components/charts/pie-chart/utils/interface.d.ts.map +1 -1
- package/dist/components/image-cropper/image-cropper.d.ts +2 -2
- package/dist/components/image-cropper/image-cropper.d.ts.map +1 -1
- package/dist/components/image-cropper/image-cropper.js +2 -2
- package/dist/components/image-cropper/image-cropper.js.map +1 -1
- package/dist/components/image-cropper/image-cropper.stories.js +5 -8
- package/dist/components/image-cropper/image-cropper.stories.js.map +1 -1
- package/dist/components/stat/stat-card.d.ts +5 -3
- package/dist/components/stat/stat-card.d.ts.map +1 -1
- package/dist/components/stat/stat-card.js +12 -6
- package/dist/components/stat/stat-card.js.map +1 -1
- package/dist/components/stat/stat-cards.stories.d.ts +3 -2
- package/dist/components/stat/stat-cards.stories.d.ts.map +1 -1
- package/dist/components/stat/stat-cards.stories.js +2 -1
- package/dist/components/stat/stat-cards.stories.js.map +1 -1
- package/dist/components/stat/stat-extended-card.d.ts.map +1 -1
- package/dist/components/stat/stat-extended-card.stories.d.ts +2 -2
- package/dist/components/stat/stat-extended-card.stories.d.ts.map +1 -1
- package/dist/components/stat/stat-extended-card.stories.js.map +1 -1
- package/dist/components/ui/centered-spinner.d.ts +2 -2
- package/dist/components/ui/centered-spinner.d.ts.map +1 -1
- package/dist/components/ui/centered-spinner.js +1 -1
- package/dist/components/ui/centered-spinner.js.map +1 -1
- package/dist/components/ui/centered-spinner.stories.d.ts +2 -2
- package/dist/components/ui/centered-spinner.stories.d.ts.map +1 -1
- package/dist/components/ui/centered-spinner.stories.js.map +1 -1
- package/dist/components/ui/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/ui/date-range-picker/date-range-picker.stories.js.map +1 -1
- package/dist/components/ui/disabled-button.d.ts +2 -2
- package/dist/components/ui/disabled-button.d.ts.map +1 -1
- package/dist/components/ui/disabled-button.js.map +1 -1
- package/dist/components/ui/line-text/line-text-body.stories.d.ts +2 -2
- package/dist/components/ui/line-text/line-text-body.stories.d.ts.map +1 -1
- package/dist/components/ui/line-text/line-text-body.stories.js.map +1 -1
- package/dist/components/ui/line-text/line-text-head.stories.d.ts +2 -2
- package/dist/components/ui/line-text/line-text-head.stories.d.ts.map +1 -1
- package/dist/components/ui/line-text/line-text-head.stories.js.map +1 -1
- package/dist/components/ui/line-text/line-text.d.ts +3 -3
- package/dist/components/ui/line-text/line-text.d.ts.map +1 -1
- package/dist/components/ui/line-text/line-text.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/ads-texts.d.ts +1 -1
- package/dist/utils/ads-texts.d.ts.map +1 -1
- package/dist/utils/ads-texts.js +1 -0
- package/dist/utils/ads-texts.js.map +1 -1
- package/dist/utils/format-big-numbers.d.ts +2 -0
- package/dist/utils/format-big-numbers.d.ts.map +1 -0
- package/dist/utils/format-big-numbers.js +17 -0
- package/dist/utils/format-big-numbers.js.map +1 -0
- package/dist/utils/helpers.d.ts +15 -0
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/helpers.js +41 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/use-client-rect.js +2 -21
- package/dist/utils/use-client-rect.js.map +1 -1
- package/package.json +2 -2
- package/src/components/ads/ads-stat.tsx +3 -3
- package/src/components/charts/funnel-chart/components/funnel-chart.tsx +2 -2
- package/src/components/charts/funnel-chart/components/funnel-svg.tsx +2 -2
- package/src/components/charts/funnel-chart/funnel-chart.stories.tsx +2 -2
- package/src/components/charts/line-chart/components/body.tsx +4 -4
- package/src/components/charts/line-chart/components/container.tsx +2 -2
- package/src/components/charts/line-chart/components/hover-popover.tsx +4 -4
- package/src/components/charts/line-chart/components/sidebar.tsx +2 -2
- package/src/components/charts/line-chart/components/stuff.tsx +4 -4
- package/src/components/charts/line-chart/components/svg-bars.tsx +3 -3
- package/src/components/charts/line-chart/components/svg-body.tsx +4 -4
- package/src/components/charts/line-chart/components/svg-lines.tsx +3 -3
- package/src/components/charts/line-chart/line-chart.stories.tsx +1 -1
- package/src/components/charts/line-chart/utils/interfaces.ts +2 -2
- package/src/components/charts/pie-chart/components/pie-chart.tsx +20 -7
- package/src/components/charts/pie-chart/components/pie.tsx +42 -22
- package/src/components/charts/pie-chart/pie-chart.stories.tsx +20 -1
- package/src/components/charts/pie-chart/utils/const.ts +11 -6
- package/src/components/charts/pie-chart/utils/interface.ts +5 -2
- package/src/components/image-cropper/image-cropper.stories.tsx +8 -8
- package/src/components/image-cropper/image-cropper.tsx +2 -2
- package/src/components/stat/stat-card.tsx +17 -6
- package/src/components/stat/stat-cards.stories.tsx +5 -2
- package/src/components/stat/stat-extended-card.stories.tsx +2 -2
- package/src/components/stat/stat-extended-card.tsx +1 -1
- package/src/components/ui/centered-spinner.stories.tsx +2 -2
- package/src/components/ui/centered-spinner.tsx +2 -6
- package/src/components/ui/date-range-picker/date-range-picker.stories.tsx +2 -2
- package/src/components/ui/date-range-picker/date-range-picker.tsx +1 -1
- package/src/components/ui/disabled-button.tsx +2 -2
- package/src/components/ui/line-text/line-text-body.stories.tsx +2 -2
- package/src/components/ui/line-text/line-text-head.stories.tsx +2 -2
- package/src/components/ui/line-text/line-text.tsx +3 -11
- package/src/index.ts +1 -0
- package/src/utils/__tests__/format-big-numbers.test.ts +17 -0
- package/src/utils/__tests__/helpers.test.ts +31 -0
- package/src/utils/ads-texts.tsx +3 -0
- package/src/utils/format-big-numbers.ts +15 -0
- package/src/utils/helpers.ts +43 -0
- package/src/utils/use-client-rect.ts +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
2
|
import { CenteredSpinner } from './centered-spinner';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
@@ -7,7 +7,7 @@ export default {
|
|
|
7
7
|
parameters: {},
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
const w = (style: { width?: string; height?: string }, cb: () =>
|
|
10
|
+
const w = (style: { width?: string; height?: string }, cb: () => ReactElement) => () =>
|
|
11
11
|
<div style={style}>{cb()}</div>;
|
|
12
12
|
|
|
13
13
|
export const centeredSpinnerTiny = w({}, () => <CenteredSpinner size="tiny" />);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FC } from 'react';
|
|
2
2
|
import classnames from 'classnames';
|
|
3
3
|
import { BodyText, Stack, Spinner } from '@servicetitan/design-system';
|
|
4
4
|
|
|
@@ -9,11 +9,7 @@ export interface CenteredSpinnerPropsStrict {
|
|
|
9
9
|
info?: string;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export const CenteredSpinner:
|
|
13
|
-
size,
|
|
14
|
-
className,
|
|
15
|
-
info,
|
|
16
|
-
}) => {
|
|
12
|
+
export const CenteredSpinner: FC<CenteredSpinnerPropsStrict> = ({ size, className, info }) => {
|
|
17
13
|
return (
|
|
18
14
|
<Stack
|
|
19
15
|
justifyContent="center"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FC } from 'react';
|
|
2
2
|
import { DateRangePicker } from './date-range-picker';
|
|
3
3
|
import { DateRangePickerState, DateRangePickerOptionsTenantAds } from '../../../utils/date';
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
const tz = { UtcOffset: 0 };
|
|
12
12
|
const state = DateRangePickerState.createWithOptions(DateRangePickerOptionsTenantAds.create(tz));
|
|
13
13
|
|
|
14
|
-
const w = (style: { width?: string; height?: string }, Component:
|
|
14
|
+
const w = (style: { width?: string; height?: string }, Component: FC) => () =>
|
|
15
15
|
(
|
|
16
16
|
<div style={style}>
|
|
17
17
|
<Component />
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FC } from 'react';
|
|
2
2
|
import { Button, ButtonProps, Tooltip } from '@servicetitan/design-system';
|
|
3
3
|
|
|
4
4
|
interface DisabledButtonProps extends Omit<ButtonProps, 'disabled'> {
|
|
@@ -14,7 +14,7 @@ interface DisabledButtonProps extends Omit<ButtonProps, 'disabled'> {
|
|
|
14
14
|
* <DisabledButton disabled="This button is disabled">knock knock</Button>
|
|
15
15
|
* )
|
|
16
16
|
*/
|
|
17
|
-
export const DisabledButton:
|
|
17
|
+
export const DisabledButton: FC<DisabledButtonProps> = props => {
|
|
18
18
|
return props.disabled && props.disabled !== true ? (
|
|
19
19
|
<Tooltip text={props.disabled}>
|
|
20
20
|
<Button {...props} disabled />
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
2
|
import { BodyTextLine } from './line-text';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
@@ -7,7 +7,7 @@ export default {
|
|
|
7
7
|
parameters: {},
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
const w = (style: { width?: string }, cb: () =>
|
|
10
|
+
const w = (style: { width?: string }, cb: () => ReactElement) => () =>
|
|
11
11
|
<div style={style}>{cb()}</div>;
|
|
12
12
|
|
|
13
13
|
export const bodyTextLineUnlimited = w({}, () => <BodyTextLine>just a simple text</BodyTextLine>);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
2
|
import { HeadlineLine } from './line-text';
|
|
3
3
|
|
|
4
4
|
export default {
|
|
@@ -7,7 +7,7 @@ export default {
|
|
|
7
7
|
parameters: {},
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
const w = (style: { width?: string }, cb: () =>
|
|
10
|
+
const w = (style: { width?: string }, cb: () => ReactElement) => () =>
|
|
11
11
|
<div style={style}>{cb()}</div>;
|
|
12
12
|
|
|
13
13
|
export const headlineLineUnlimited = w({}, () => <HeadlineLine>just a simple text</HeadlineLine>);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useMemo, FC } from 'react';
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import {
|
|
4
4
|
BodyText,
|
|
@@ -30,11 +30,7 @@ export interface BodyTextLineProps extends BodyTextPropsStrict {
|
|
|
30
30
|
children?: string;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export const BodyTextLine:
|
|
34
|
-
children,
|
|
35
|
-
wrapperClassName,
|
|
36
|
-
...props
|
|
37
|
-
}) => {
|
|
33
|
+
export const BodyTextLine: FC<BodyTextLineProps> = ({ children, wrapperClassName, ...props }) => {
|
|
38
34
|
const [ref1, ref2, limited] = useLimited();
|
|
39
35
|
|
|
40
36
|
return (
|
|
@@ -79,11 +75,7 @@ export interface HeadlineLineProps extends HeadlinePropsStrict {
|
|
|
79
75
|
children?: string;
|
|
80
76
|
}
|
|
81
77
|
|
|
82
|
-
export const HeadlineLine:
|
|
83
|
-
children,
|
|
84
|
-
wrapperClassName,
|
|
85
|
-
...props
|
|
86
|
-
}) => {
|
|
78
|
+
export const HeadlineLine: FC<HeadlineLineProps> = ({ children, wrapperClassName, ...props }) => {
|
|
87
79
|
const [ref1, ref2, limited] = useLimited();
|
|
88
80
|
|
|
89
81
|
return (
|
package/src/index.ts
CHANGED
|
@@ -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
|
+
});
|
package/src/utils/ads-texts.tsx
CHANGED
|
@@ -7,6 +7,7 @@ export type AdsStatType =
|
|
|
7
7
|
| 'closeRate'
|
|
8
8
|
| 'sessions'
|
|
9
9
|
| 'conversions'
|
|
10
|
+
| 'allConversions'
|
|
10
11
|
| 'transactions'
|
|
11
12
|
| 'bookedJobs'
|
|
12
13
|
| 'ranJobs'
|
|
@@ -42,6 +43,8 @@ export const adsStatDescriptions: Record<AdsStatType, string> = {
|
|
|
42
43
|
"The number of times your website registered a visitor. This can differ from clicks because clicks can include clicks on extensions on the ad that don't lead to the website, like call extensions. Also, some clickers immediately leave the website before the website can register a session",
|
|
43
44
|
conversions:
|
|
44
45
|
'The number of people who took a predesignated action resulting from a marketing campaign. This typically includes Phone Calls, Form Submissions, Appointments Booked, and Live Chats',
|
|
46
|
+
allConversions:
|
|
47
|
+
'Every conversion reported by Google Ads, including those that are marked to NOT be included in the Conversions column',
|
|
45
48
|
transactions: 'The number of completed jobs where revenue was generated',
|
|
46
49
|
leads: 'Phone Calls that are longer than 60 seconds and not dismissed, plus online bookings and manual jobs',
|
|
47
50
|
ranJobs:
|
|
@@ -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
|
+
};
|
package/src/utils/helpers.ts
CHANGED
|
@@ -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
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
export const useClientRect = (): [
|
|
4
4
|
DOMRect | null,
|
|
@@ -41,7 +41,7 @@ export const useClientRect = (): [
|
|
|
41
41
|
return () => clearTimeout(to);
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
const ref =
|
|
44
|
+
const ref = useCallback(
|
|
45
45
|
(node: HTMLElement | null) => {
|
|
46
46
|
if (node !== null) {
|
|
47
47
|
window.addEventListener('resize', handleResize);
|