@servicetitan/marketing-ui 0.5.0 → 0.8.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 (106) hide show
  1. package/dist/components/image-cropper/image-cropper.d.ts +23 -0
  2. package/dist/components/image-cropper/image-cropper.d.ts.map +1 -0
  3. package/dist/components/image-cropper/image-cropper.js +146 -0
  4. package/dist/components/image-cropper/image-cropper.js.map +1 -0
  5. package/dist/components/image-cropper/image-cropper.stories.d.ts +10 -0
  6. package/dist/components/image-cropper/image-cropper.stories.d.ts.map +1 -0
  7. package/dist/components/image-cropper/image-cropper.stories.js +55 -0
  8. package/dist/components/image-cropper/image-cropper.stories.js.map +1 -0
  9. package/dist/components/ui/date-range-picker/date-range-picker.d.ts +10 -0
  10. package/dist/components/ui/date-range-picker/date-range-picker.d.ts.map +1 -0
  11. package/dist/components/ui/date-range-picker/date-range-picker.js +77 -0
  12. package/dist/components/ui/date-range-picker/date-range-picker.js.map +1 -0
  13. package/dist/components/ui/date-range-picker/date-range-picker.module.less +42 -0
  14. package/dist/components/ui/date-range-picker/date-range-picker.stories.d.ts +10 -0
  15. package/dist/components/ui/date-range-picker/date-range-picker.stories.d.ts.map +1 -0
  16. package/dist/components/ui/date-range-picker/date-range-picker.stories.js +17 -0
  17. package/dist/components/ui/date-range-picker/date-range-picker.stories.js.map +1 -0
  18. package/dist/index.d.ts +2 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +2 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/utils/date/__mocks__/date-mock.d.ts +5 -0
  23. package/dist/utils/date/__mocks__/date-mock.d.ts.map +1 -0
  24. package/dist/utils/date/__mocks__/date-mock.js +23 -0
  25. package/dist/utils/date/__mocks__/date-mock.js.map +1 -0
  26. package/dist/utils/date/date-range-picker-options.d.ts +45 -0
  27. package/dist/utils/date/date-range-picker-options.d.ts.map +1 -0
  28. package/dist/utils/date/date-range-picker-options.js +138 -0
  29. package/dist/utils/date/date-range-picker-options.js.map +1 -0
  30. package/dist/utils/date/date-range-picker-state.d.ts +24 -0
  31. package/dist/utils/date/date-range-picker-state.d.ts.map +1 -0
  32. package/dist/utils/date/date-range-picker-state.js +73 -0
  33. package/dist/utils/date/date-range-picker-state.js.map +1 -0
  34. package/dist/utils/date/date-tenant.d.ts +17 -0
  35. package/dist/utils/date/date-tenant.d.ts.map +1 -0
  36. package/dist/utils/date/date-tenant.js +51 -0
  37. package/dist/utils/date/date-tenant.js.map +1 -0
  38. package/dist/utils/date/date.d.ts +11 -0
  39. package/dist/utils/date/date.d.ts.map +1 -0
  40. package/dist/utils/date/date.js +22 -0
  41. package/dist/utils/date/date.js.map +1 -0
  42. package/dist/utils/date/index.d.ts +5 -0
  43. package/dist/utils/date/index.d.ts.map +1 -0
  44. package/dist/utils/date/index.js +17 -0
  45. package/dist/utils/date/index.js.map +1 -0
  46. package/dist/utils/history/history.d.ts +9 -3
  47. package/dist/utils/history/history.d.ts.map +1 -1
  48. package/dist/utils/history/history.js +9 -7
  49. package/dist/utils/history/history.js.map +1 -1
  50. package/dist/utils/history/index.d.ts +1 -0
  51. package/dist/utils/history/index.d.ts.map +1 -1
  52. package/dist/utils/history/index.js +1 -0
  53. package/dist/utils/history/index.js.map +1 -1
  54. package/dist/utils/history/query-params-handler.d.ts +1 -0
  55. package/dist/utils/history/query-params-handler.d.ts.map +1 -1
  56. package/dist/utils/history/query-params-handler.js +3 -0
  57. package/dist/utils/history/query-params-handler.js.map +1 -1
  58. package/dist/utils/history/url-params-handler.d.ts +18 -0
  59. package/dist/utils/history/url-params-handler.d.ts.map +1 -0
  60. package/dist/utils/history/url-params-handler.js +64 -0
  61. package/dist/utils/history/url-params-handler.js.map +1 -0
  62. package/dist/utils/history/use-query-params.d.ts.map +1 -1
  63. package/dist/utils/history/use-query-params.js +5 -3
  64. package/dist/utils/history/use-query-params.js.map +1 -1
  65. package/dist/utils/history/use-url-params.d.ts +5 -5
  66. package/dist/utils/history/use-url-params.d.ts.map +1 -1
  67. package/dist/utils/history/use-url-params.js +4 -19
  68. package/dist/utils/history/use-url-params.js.map +1 -1
  69. package/dist/utils/{use-init-effect.d.ts → invariable-hooks.d.ts} +6 -1
  70. package/dist/utils/invariable-hooks.d.ts.map +1 -0
  71. package/dist/utils/{use-init-effect.js → invariable-hooks.js} +11 -2
  72. package/dist/utils/invariable-hooks.js.map +1 -0
  73. package/dist/utils/param-parsers.d.ts +2 -1
  74. package/dist/utils/param-parsers.d.ts.map +1 -1
  75. package/dist/utils/param-parsers.js +21 -1
  76. package/dist/utils/param-parsers.js.map +1 -1
  77. package/package.json +5 -3
  78. package/src/components/image-cropper/image-cropper.stories.tsx +69 -0
  79. package/src/components/image-cropper/image-cropper.tsx +108 -0
  80. package/src/components/ui/date-range-picker/date-range-picker.module.less +42 -0
  81. package/src/components/ui/date-range-picker/date-range-picker.module.less.d.ts +4 -0
  82. package/src/components/ui/date-range-picker/date-range-picker.stories.tsx +22 -0
  83. package/src/components/ui/date-range-picker/date-range-picker.tsx +118 -0
  84. package/src/index.ts +2 -1
  85. package/src/utils/__tests__/param-parsers.test.ts +11 -2
  86. package/src/utils/date/__mocks__/date-mock.ts +23 -0
  87. package/src/utils/date/__tests__/date-range-picker.test.ts +139 -0
  88. package/src/utils/date/__tests__/date-tenant.test.ts +38 -0
  89. package/src/utils/date/date-range-picker-options.ts +167 -0
  90. package/src/utils/date/date-range-picker-state.ts +62 -0
  91. package/src/utils/date/date-tenant.ts +49 -0
  92. package/src/utils/date/date.ts +29 -0
  93. package/src/utils/date/index.ts +4 -0
  94. package/src/utils/history/__tests__/history.test.ts +9 -2
  95. package/src/utils/history/__tests__/url-params-handler.test.ts +32 -0
  96. package/src/utils/history/__tests__/use-url-params.test.ts +2 -1
  97. package/src/utils/history/history.ts +27 -10
  98. package/src/utils/history/index.ts +1 -0
  99. package/src/utils/history/query-params-handler.ts +4 -0
  100. package/src/utils/history/url-params-handler.ts +65 -0
  101. package/src/utils/history/use-query-params.ts +5 -3
  102. package/src/utils/history/use-url-params.ts +7 -32
  103. package/src/utils/{use-init-effect.ts → invariable-hooks.ts} +10 -1
  104. package/src/utils/param-parsers.ts +26 -1
  105. package/dist/utils/use-init-effect.d.ts.map +0 -1
  106. package/dist/utils/use-init-effect.js.map +0 -1
@@ -9,7 +9,7 @@ type Keys = 'lorem' | 'ipsum' | 'dolor';
9
9
 
10
10
  interface UrlParams {
11
11
  lorem: { year: number };
12
- ipsum: { name: 'Search' | 'Display' };
12
+ ipsum: { name?: 'Search' | 'Display' };
13
13
  }
14
14
 
15
15
  interface QueryParams {
@@ -19,7 +19,7 @@ interface QueryParams {
19
19
  const UrlMap: Record<Keys, string> = {
20
20
  dolor: '/',
21
21
  lorem: '/lorem/:year(\\d+)',
22
- ipsum: '/ipsum/:name(Search|Display)',
22
+ ipsum: '/ipsum/:name(Search|Display)?',
23
23
  };
24
24
 
25
25
  const handlers = {
@@ -48,6 +48,7 @@ describe('useParamsHistory', () => {
48
48
  cb(
49
49
  useParamsHistory<Keys, UrlParams, QueryParams>(
50
50
  UrlMap,
51
+ undefined,
51
52
  paramHandler ? handlers : undefined
52
53
  )
53
54
  )
@@ -81,6 +82,12 @@ describe('useParamsHistory', () => {
81
82
  expect(result).toBe('/ipsum/Search');
82
83
  });
83
84
 
85
+ it('check optional url params', () => {
86
+ const result = renderHookText(hook => hook.href('ipsum'));
87
+
88
+ expect(result).toBe('/ipsum');
89
+ });
90
+
84
91
  it('uses query param handler', () => {
85
92
  const result = renderHookText(
86
93
  hook => hook.href('dolor', undefined, { to: 'Search', from: new Date(2021, 8, 9) }),
@@ -0,0 +1,32 @@
1
+ import { UrlParamsHandler } from '../url-params-handler';
2
+
3
+ describe('UrlParamsHandler', () => {
4
+ const handler = new UrlParamsHandler<{
5
+ str?: string;
6
+ numb?: number;
7
+ bool?: boolean;
8
+ dt?: Date;
9
+ strArr?: string[];
10
+ numbArr?: number[];
11
+ }>({
12
+ str: UrlParamsHandler.parserString,
13
+ numb: UrlParamsHandler.parserNumber,
14
+ });
15
+
16
+ it('parses url params', () => {
17
+ const result = handler.parse({ str: 'check', numb: '12' });
18
+
19
+ expect(result).toEqual({
20
+ str: 'check',
21
+ numb: 12,
22
+ });
23
+ });
24
+
25
+ it('generates url string', () => {
26
+ const result = handler.toString({
27
+ numb: 15,
28
+ });
29
+
30
+ expect(result).toEqual({ numb: '15' });
31
+ });
32
+ });
@@ -4,6 +4,7 @@ import { createMemoryHistory, History } from 'history';
4
4
  import { Router, Route } from 'react-router-dom';
5
5
  import { useUrlParams } from '../use-url-params';
6
6
  import { paramParsers, StringParamParser } from '../../param-parsers';
7
+ import { UrlParamsHandler } from '../url-params-handler';
7
8
 
8
9
  type ParsersFromValues<Values extends Record<string, any | undefined>> = {
9
10
  [Prop in keyof Values]: StringParamParser<Values[Prop]>;
@@ -30,7 +31,7 @@ describe('useUrlParams', () => {
30
31
  Route,
31
32
  { path },
32
33
  React.createElement(() => {
33
- result = useUrlParams(paramHandler);
34
+ result = useUrlParams(UrlParamsHandler.from(paramHandler));
34
35
 
35
36
  return null;
36
37
  })
@@ -1,7 +1,8 @@
1
- import { useMemo } from 'react';
2
1
  import { useHistory, generatePath } from 'react-router-dom';
3
- import { createPath } from 'history';
2
+ import { createPath, History } from 'history';
3
+ import { useInvariableMemo } from '../invariable-hooks';
4
4
  import { QueryParamsHandler } from './query-params-handler';
5
+ import { UrlParamsHandler } from './url-params-handler';
5
6
 
6
7
  type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
7
8
  ? I
@@ -17,12 +18,17 @@ export interface ParametrizedHistory<
17
18
  href: Overloading<Keys, UrlMappings, QueryMappings, string>;
18
19
  push: Overloading<Keys, UrlMappings, QueryMappings, void>;
19
20
  replace: Overloading<Keys, UrlMappings, QueryMappings, void>;
21
+ history: History;
20
22
  }
21
23
 
22
24
  type AllOverloads<Keys extends string, UrlMappings, QueryMappings, O> = {
23
25
  [Prop in Keys]: Prop extends keyof UrlMappings
24
26
  ? Prop extends keyof QueryMappings
25
- ? (key: Prop, urlParams: UrlMappings[Prop], queryParams?: QueryMappings[Prop]) => O
27
+ ? Partial<UrlMappings[Prop]> extends UrlMappings[Prop]
28
+ ? (key: Prop, urlParams?: UrlMappings[Prop], queryParams?: QueryMappings[Prop]) => O
29
+ : (key: Prop, urlParams: UrlMappings[Prop], queryParams?: QueryMappings[Prop]) => O
30
+ : Partial<UrlMappings[Prop]> extends UrlMappings[Prop]
31
+ ? (key: Prop, urlParams?: UrlMappings[Prop]) => O
26
32
  : (key: Prop, urlParams: UrlMappings[Prop]) => O
27
33
  : Prop extends keyof QueryMappings
28
34
  ? (key: Prop, urlParams?: undefined, queryParams?: QueryMappings[Prop]) => O
@@ -33,10 +39,14 @@ type Overloading<Keys extends string, UrlMappings, QueryMappings, O> = UnionToIn
33
39
  Values<AllOverloads<Keys, UrlMappings, QueryMappings, O>>
34
40
  >;
35
41
 
36
- type ParamHandlers<QueryMappings> = {
42
+ type QueryParamHandlers<QueryMappings> = {
37
43
  [Prop in keyof QueryMappings]?: QueryParamsHandler<QueryMappings[Prop]>;
38
44
  };
39
45
 
46
+ type UrlParamHandlers<QueryMappings> = {
47
+ [Prop in keyof QueryMappings]?: UrlParamsHandler<QueryMappings[Prop]>;
48
+ };
49
+
40
50
  /**
41
51
  * Create parameterized history to check passed arguments
42
52
  *
@@ -75,16 +85,17 @@ type ParamHandlers<QueryMappings> = {
75
85
  */
76
86
  export const useParamsHistory = <Keys extends string, PU = void, PQ = void>(
77
87
  paths: Record<Keys, string>,
78
- handlers?: ParamHandlers<PQ>
88
+ urlHandlers?: UrlParamHandlers<PU>,
89
+ queryHandlers?: QueryParamHandlers<PQ>
79
90
  ): ParametrizedHistory<Keys, PU, PQ> => {
80
91
  const history = useHistory();
81
92
 
82
- return useMemo(() => {
93
+ return useInvariableMemo(() => {
83
94
  const generateLocation = (path: Keys, urlParams?: any, queryParams?: any) => {
84
95
  let searchParams = undefined;
85
96
 
86
97
  if (queryParams) {
87
- const hand = (handlers as any)?.[path as any] as QueryParamsHandler<any>;
98
+ const hand = (queryHandlers as any)?.[path as any] as QueryParamsHandler<any>;
88
99
 
89
100
  if (hand) {
90
101
  searchParams = '?' + hand.toString(queryParams);
@@ -93,13 +104,19 @@ export const useParamsHistory = <Keys extends string, PU = void, PQ = void>(
93
104
  }
94
105
  }
95
106
 
107
+ const urlHandler = (urlHandlers as any)?.[path] as UrlParamsHandler<any>;
108
+
96
109
  return {
97
- pathname: generatePath(paths[path], urlParams),
110
+ pathname: generatePath(
111
+ paths[path],
112
+ urlHandler ? urlHandler.toString(urlParams) : urlParams
113
+ ),
98
114
  search: searchParams,
99
115
  };
100
116
  };
101
117
 
102
118
  return {
119
+ history,
103
120
  path: ((key: Keys, urlParams?: unknown, queryParams?: unknown) => {
104
121
  return createPath(generateLocation(key, urlParams, queryParams));
105
122
  }) as Overloading<Keys, PU, PQ, string>,
@@ -111,9 +128,9 @@ export const useParamsHistory = <Keys extends string, PU = void, PQ = void>(
111
128
  push: ((key: Keys, urlParams?: unknown, queryParams?: unknown) => {
112
129
  history.push(createPath(generateLocation(key, urlParams, queryParams)));
113
130
  }) as Overloading<Keys, PU, PQ, void>,
114
- replace: ((key: Keys, urlParams?: unknown, queryParams?: unknown) => {
131
+ replace: ((key: Keys, urlParams?: Partial<PU>, queryParams?: unknown) => {
115
132
  history.replace(createPath(generateLocation(key, urlParams, queryParams)));
116
133
  }) as Overloading<Keys, PU, PQ, void>,
117
134
  };
118
- }, [history, paths, handlers]);
135
+ });
119
136
  };
@@ -1,4 +1,5 @@
1
1
  export * from './history';
2
2
  export * from './query-params-handler';
3
+ export * from './url-params-handler';
3
4
  export * from './use-query-params';
4
5
  export * from './use-url-params';
@@ -80,6 +80,10 @@ export class QueryParamsHandler<Values extends Record<string, any | undefined>>
80
80
 
81
81
  constructor(private handlers: HandlersFromValues<Values>) {}
82
82
 
83
+ static from<T>(handlers: HandlersFromValues<T>) {
84
+ return new QueryParamsHandler<T>(handlers);
85
+ }
86
+
83
87
  toString(params: Values): string {
84
88
  const keys = Object.keys(this.handlers);
85
89
  const url = new URLSearchParams();
@@ -0,0 +1,65 @@
1
+ import { paramParsers, StringParamParser } from '../param-parsers';
2
+ import { keys } from '../helpers';
3
+
4
+ type HandlersFromValues<Values extends Record<string, any | undefined>> = {
5
+ [Prop in keyof Values]: StringParamParser<Values[Prop]>;
6
+ };
7
+
8
+ type StringParams<T extends Record<string, any>> = {
9
+ [Prop in keyof T]: string | undefined;
10
+ };
11
+
12
+ export class UrlParamsHandler<Values extends Record<string, any | undefined>> {
13
+ static readonly parserString = paramParsers.uri;
14
+ static readonly parserNumber = paramParsers.number;
15
+
16
+ constructor(private parsers: HandlersFromValues<Values>) {}
17
+
18
+ static from<T>(parsers: HandlersFromValues<T>) {
19
+ return new UrlParamsHandler<T>(parsers);
20
+ }
21
+
22
+ toString(values?: Partial<Values>): Partial<StringParams<Values>> {
23
+ const params: Partial<StringParams<Values>> = {};
24
+
25
+ if (!values) {
26
+ return params;
27
+ }
28
+
29
+ for (const key of keys(values)) {
30
+ const parser = this.parsers[key];
31
+
32
+ if (!parser) {
33
+ continue;
34
+ }
35
+
36
+ const value = values[key];
37
+
38
+ if (value !== undefined) {
39
+ params[key] = parser.stringify(value!);
40
+ }
41
+ }
42
+
43
+ return params;
44
+ }
45
+
46
+ parse(params: StringParams<Values>): Partial<Values> {
47
+ const values: Partial<Values> = {};
48
+
49
+ for (const key of keys(params)) {
50
+ const parser = this.parsers?.[key];
51
+
52
+ if (!parser) {
53
+ continue;
54
+ }
55
+
56
+ const value = params[key];
57
+
58
+ if (value !== undefined) {
59
+ values[key] = parser.parse(value);
60
+ }
61
+ }
62
+
63
+ return values;
64
+ }
65
+ }
@@ -2,6 +2,7 @@ import { useMemo } from 'react';
2
2
  import { useHistory } from 'react-router-dom';
3
3
  import { createPath } from 'history';
4
4
  import { QueryParamsHandler } from './query-params-handler';
5
+ import { useInvariableMemo } from '../invariable-hooks';
5
6
 
6
7
  export interface QueryParamsHook<T extends Record<string, any | undefined>> {
7
8
  values: T;
@@ -32,11 +33,12 @@ function useQueryParams<T extends Record<string, any>>(
32
33
  function useQueryParams<T>(handler?: QueryParamsHandler<T>): QueryParamsHook<T> {
33
34
  const history = useHistory();
34
35
  const search = history.location.search || '';
36
+ const memoHandler = useInvariableMemo(() => handler);
35
37
 
36
38
  return useMemo(() => {
37
- const currentValues = handler ? handler.parse(search) : parseParams<T>(search);
39
+ const currentValues = memoHandler ? memoHandler.parse(search) : parseParams<T>(search);
38
40
  const stringify = (params: T) =>
39
- handler ? handler.toString(params) : stringifyParams(params);
41
+ memoHandler ? memoHandler.toString(params) : stringifyParams(params);
40
42
 
41
43
  const createPathWithParams = (pathName: string, params: T) =>
42
44
  createPath({ pathname: pathName, search: stringify(params) });
@@ -61,7 +63,7 @@ function useQueryParams<T>(handler?: QueryParamsHandler<T>): QueryParamsHook<T>
61
63
  pathname: createPath({ pathname: pathName, search: stringify(params) }),
62
64
  }),
63
65
  };
64
- }, [search, handler, history]);
66
+ }, [search, memoHandler, history]);
65
67
  }
66
68
 
67
69
  export { useQueryParams };
@@ -1,44 +1,19 @@
1
1
  import { useMemo } from 'react';
2
2
  import { useParams } from 'react-router-dom';
3
- import { StringParamParser } from '../param-parsers';
4
- import { keys } from '../helpers';
3
+ import { UrlParamsHandler } from './url-params-handler';
4
+ import { useInvariableMemo } from '../invariable-hooks';
5
5
 
6
6
  type StringParams<T extends Record<string, any>> = {
7
7
  [Prop in keyof T]: string | undefined;
8
8
  };
9
9
 
10
- type ParsersFromValues<Values extends Record<string, any | undefined>> = {
11
- [Prop in keyof Values]: StringParamParser<Values[Prop]>;
12
- };
13
-
14
- function useUrlParams<T extends Record<string, string>>(): Partial<T>;
15
- function useUrlParams<T extends Record<string, any>>(parsers: ParsersFromValues<T>): Partial<T>;
16
- function useUrlParams<T>(parsers?: ParsersFromValues<T>): Partial<T> {
10
+ function useUrlParams<T extends Record<string, string>>(): StringParams<T>;
11
+ function useUrlParams<T extends Record<string, any>>(parsers: UrlParamsHandler<T>): Partial<T>;
12
+ function useUrlParams<T>(handler?: UrlParamsHandler<T>): Partial<T> | StringParams<T> {
17
13
  const params = useParams<StringParams<T>>();
14
+ const memoHandler = useInvariableMemo(() => handler);
18
15
 
19
- return useMemo(() => {
20
- if (!parsers) {
21
- return params as unknown as Partial<T>;
22
- }
23
-
24
- const values: Partial<T> = {};
25
-
26
- for (const key of keys(params)) {
27
- const parser = parsers[key];
28
-
29
- if (!parser) {
30
- continue;
31
- }
32
-
33
- const value = params[key];
34
-
35
- if (value !== undefined) {
36
- values[key] = parser.parse(value);
37
- }
38
- }
39
-
40
- return values;
41
- }, [parsers, params]);
16
+ return useMemo(() => (memoHandler ? memoHandler.parse(params) : params), [params, memoHandler]);
42
17
  }
43
18
 
44
19
  export { useUrlParams };
@@ -1,4 +1,4 @@
1
- import { useEffect } from 'react';
1
+ import { useEffect, useMemo } from 'react';
2
2
 
3
3
  /**
4
4
  * runs effect only once for component
@@ -13,3 +13,12 @@ export function useInitEffect(init: () => void, dispose?: () => void) {
13
13
  // eslint-disable-next-line react-hooks/exhaustive-deps
14
14
  }, []);
15
15
  }
16
+
17
+ /**
18
+ * gets memo only once
19
+ * @param memo method that returns memoed data
20
+ */
21
+ export function useInvariableMemo<T>(memo: () => T): T {
22
+ // eslint-disable-next-line react-hooks/exhaustive-deps
23
+ return useMemo(memo, []);
24
+ }
@@ -1,3 +1,5 @@
1
+ import { keys } from './helpers';
2
+
1
3
  export interface StringParamParser<T> {
2
4
  stringify(value: T): string | undefined;
3
5
  parse(query: string): T | undefined;
@@ -12,7 +14,7 @@ const stringParser: StringParamParser<string> = {
12
14
  },
13
15
  };
14
16
 
15
- const stringEnumParser = <T extends string>(values: T[]): StringParamParser<T> => ({
17
+ const stringSetParser = <T extends string>(values: (string | T)[]): StringParamParser<T> => ({
16
18
  stringify(value) {
17
19
  return value || undefined;
18
20
  },
@@ -25,6 +27,28 @@ const stringEnumParser = <T extends string>(values: T[]): StringParamParser<T> =
25
27
  },
26
28
  });
27
29
 
30
+ const stringEnumParser = <TS extends string, TV>(map: Record<TS, TV>): StringParamParser<TV> => ({
31
+ stringify(value) {
32
+ for (const key of keys(map)) {
33
+ if (map[key] === value) {
34
+ return key;
35
+ }
36
+ }
37
+
38
+ return undefined;
39
+ },
40
+ parse(query) {
41
+ const key = query as TS;
42
+
43
+ // eslint-disable-next-line no-prototype-builtins
44
+ if (map.hasOwnProperty(key)) {
45
+ return map[key];
46
+ }
47
+
48
+ return undefined;
49
+ },
50
+ });
51
+
28
52
  const uriParser: StringParamParser<string> = {
29
53
  stringify(value) {
30
54
  return value || undefined;
@@ -70,6 +94,7 @@ const boolParser: StringParamParser<boolean> = {
70
94
 
71
95
  export const paramParsers = {
72
96
  string: stringParser,
97
+ stringSet: stringSetParser,
73
98
  stringEnum: stringEnumParser,
74
99
  uri: uriParser,
75
100
  number: numberParser,
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-init-effect.d.ts","sourceRoot":"","sources":["../../src/utils/use-init-effect.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,QAOnE"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-init-effect.js","sourceRoot":"","sources":["../../src/utils/use-init-effect.ts"],"names":[],"mappings":";;;AAAA,iCAAkC;AAElC;;;;GAIG;AACH,SAAgB,aAAa,CAAC,IAAgB,EAAE,OAAoB;IAChE,iBAAS,CAAC,GAAG,EAAE;QACX,IAAI,EAAE,CAAC;QAEP,OAAO,OAAO,CAAC;QACf,uDAAuD;IAC3D,CAAC,EAAE,EAAE,CAAC,CAAC;AACX,CAAC;AAPD,sCAOC"}