@gravity-ui/page-constructor 1.18.1 → 1.19.1

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 (124) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +8 -0
  3. package/build/cjs/blocks/Map/Map.d.ts +3 -0
  4. package/build/cjs/blocks/Map/Map.js +15 -0
  5. package/build/cjs/blocks/Map/schema.d.ts +384 -0
  6. package/build/cjs/blocks/Map/schema.js +18 -0
  7. package/build/cjs/blocks/Media/Media.js +5 -27
  8. package/build/cjs/blocks/Media/schema.d.ts +265 -9
  9. package/build/cjs/blocks/Media/schema.js +18 -17
  10. package/build/cjs/blocks/index.d.ts +1 -0
  11. package/build/cjs/blocks/index.js +3 -1
  12. package/build/cjs/components/Map/GoogleMap.d.ts +4 -0
  13. package/build/cjs/components/Map/GoogleMap.js +42 -0
  14. package/build/cjs/components/Map/Map.css +20 -0
  15. package/build/cjs/components/Map/Map.d.ts +3 -0
  16. package/build/cjs/components/Map/Map.js +21 -0
  17. package/build/cjs/components/Map/YMap/YMap.d.ts +13 -0
  18. package/build/cjs/components/Map/YMap/YMap.js +97 -0
  19. package/build/cjs/components/Map/YMap/YandexMap.d.ts +4 -0
  20. package/build/cjs/components/Map/YMap/YandexMap.js +72 -0
  21. package/build/cjs/components/Map/YMap/YandexMapApiLoader.d.ts +11 -0
  22. package/build/cjs/components/Map/YMap/YandexMapApiLoader.js +37 -0
  23. package/build/cjs/components/Map/YMap/i18n/en.json +4 -0
  24. package/build/cjs/components/Map/YMap/i18n/index.d.ts +2 -0
  25. package/build/cjs/components/Map/YMap/i18n/index.js +8 -0
  26. package/build/cjs/components/Map/YMap/i18n/ru.json +4 -0
  27. package/build/cjs/components/Map/helpers.d.ts +1 -0
  28. package/build/cjs/components/Map/helpers.js +7 -0
  29. package/build/cjs/{blocks/Media/Media.css → components/MediaBase/MediaBase.css} +15 -14
  30. package/build/cjs/components/MediaBase/MediaBase.d.ts +13 -0
  31. package/build/cjs/components/MediaBase/MediaBase.js +39 -0
  32. package/build/{esm/blocks/Media/MediaContent.css → cjs/components/MediaBase/MediaBaseContent.css} +2 -2
  33. package/build/cjs/{blocks/Media/MediaContent.js → components/MediaBase/MediaBaseContent.js} +1 -1
  34. package/build/cjs/constructor-items.d.ts +1 -0
  35. package/build/cjs/constructor-items.js +1 -0
  36. package/build/cjs/containers/PageConstructor/Provider.d.ts +2 -0
  37. package/build/cjs/containers/PageConstructor/Provider.js +3 -1
  38. package/build/cjs/context/mapsContext/mapsContext.d.ts +22 -0
  39. package/build/cjs/context/mapsContext/mapsContext.js +20 -0
  40. package/build/cjs/context/mapsContext/mapsProvider.d.ts +10 -0
  41. package/build/cjs/context/mapsContext/mapsProvider.js +15 -0
  42. package/build/cjs/context/mapsContext/useMap.d.ts +2 -0
  43. package/build/cjs/context/mapsContext/useMap.js +11 -0
  44. package/build/cjs/internal-typings/global.d.ts +36 -0
  45. package/build/cjs/models/constructor-items/blocks.d.ts +18 -9
  46. package/build/cjs/models/constructor-items/blocks.js +1 -0
  47. package/build/cjs/models/constructor-items/common.d.ts +25 -0
  48. package/build/cjs/schema/index.js +1 -1
  49. package/build/cjs/schema/validators/blocks.d.ts +1 -0
  50. package/build/cjs/schema/validators/blocks.js +1 -0
  51. package/build/cjs/schema/validators/common.d.ts +108 -0
  52. package/build/cjs/schema/validators/common.js +53 -1
  53. package/build/cjs/utils/blocks.d.ts +1 -1
  54. package/build/cjs/utils/common.d.ts +6 -0
  55. package/build/cjs/utils/common.js +24 -0
  56. package/build/cjs/utils/index.d.ts +1 -0
  57. package/build/cjs/utils/index.js +1 -0
  58. package/build/esm/blocks/Map/Map.d.ts +3 -0
  59. package/build/esm/blocks/Map/Map.js +11 -0
  60. package/build/esm/blocks/Map/schema.d.ts +384 -0
  61. package/build/esm/blocks/Map/schema.js +15 -0
  62. package/build/esm/blocks/Media/Media.d.ts +0 -1
  63. package/build/esm/blocks/Media/Media.js +7 -31
  64. package/build/esm/blocks/Media/schema.d.ts +265 -9
  65. package/build/esm/blocks/Media/schema.js +17 -16
  66. package/build/esm/blocks/index.d.ts +1 -0
  67. package/build/esm/blocks/index.js +1 -0
  68. package/build/esm/components/Map/GoogleMap.d.ts +4 -0
  69. package/build/esm/components/Map/GoogleMap.js +39 -0
  70. package/build/esm/components/Map/Map.css +20 -0
  71. package/build/esm/components/Map/Map.d.ts +4 -0
  72. package/build/esm/components/Map/Map.js +17 -0
  73. package/build/esm/components/Map/YMap/YMap.d.ts +13 -0
  74. package/build/esm/components/Map/YMap/YMap.js +93 -0
  75. package/build/esm/components/Map/YMap/YandexMap.d.ts +4 -0
  76. package/build/esm/components/Map/YMap/YandexMap.js +69 -0
  77. package/build/esm/components/Map/YMap/YandexMapApiLoader.d.ts +11 -0
  78. package/build/esm/components/Map/YMap/YandexMapApiLoader.js +33 -0
  79. package/build/esm/components/Map/YMap/i18n/en.json +4 -0
  80. package/build/esm/components/Map/YMap/i18n/index.d.ts +2 -0
  81. package/build/esm/components/Map/YMap/i18n/index.js +5 -0
  82. package/build/esm/components/Map/YMap/i18n/ru.json +4 -0
  83. package/build/esm/components/Map/helpers.d.ts +1 -0
  84. package/build/esm/components/Map/helpers.js +3 -0
  85. package/build/esm/{blocks/Media/Media.css → components/MediaBase/MediaBase.css} +15 -14
  86. package/build/esm/components/MediaBase/MediaBase.d.ts +14 -0
  87. package/build/esm/components/MediaBase/MediaBase.js +36 -0
  88. package/build/{cjs/blocks/Media/MediaContent.css → esm/components/MediaBase/MediaBaseContent.css} +2 -2
  89. package/build/esm/{blocks/Media/MediaContent.d.ts → components/MediaBase/MediaBaseContent.d.ts} +1 -1
  90. package/build/esm/{blocks/Media/MediaContent.js → components/MediaBase/MediaBaseContent.js} +2 -2
  91. package/build/esm/constructor-items.d.ts +1 -0
  92. package/build/esm/constructor-items.js +2 -1
  93. package/build/esm/containers/PageConstructor/Provider.d.ts +2 -0
  94. package/build/esm/containers/PageConstructor/Provider.js +3 -1
  95. package/build/esm/context/mapsContext/mapsContext.d.ts +22 -0
  96. package/build/esm/context/mapsContext/mapsContext.js +16 -0
  97. package/build/esm/context/mapsContext/mapsProvider.d.ts +10 -0
  98. package/build/esm/context/mapsContext/mapsProvider.js +10 -0
  99. package/build/esm/context/mapsContext/useMap.d.ts +2 -0
  100. package/build/esm/context/mapsContext/useMap.js +6 -0
  101. package/build/esm/internal-typings/global.d.ts +36 -0
  102. package/build/esm/models/constructor-items/blocks.d.ts +18 -9
  103. package/build/esm/models/constructor-items/blocks.js +1 -0
  104. package/build/esm/models/constructor-items/common.d.ts +25 -0
  105. package/build/esm/schema/index.js +2 -2
  106. package/build/esm/schema/validators/blocks.d.ts +1 -0
  107. package/build/esm/schema/validators/blocks.js +1 -0
  108. package/build/esm/schema/validators/common.d.ts +108 -0
  109. package/build/esm/schema/validators/common.js +52 -0
  110. package/build/esm/utils/blocks.d.ts +1 -1
  111. package/build/esm/utils/common.d.ts +6 -0
  112. package/build/esm/utils/common.js +20 -0
  113. package/build/esm/utils/index.d.ts +1 -0
  114. package/build/esm/utils/index.js +1 -0
  115. package/package.json +1 -1
  116. package/server/models/constructor-items/blocks.d.ts +18 -9
  117. package/server/models/constructor-items/blocks.js +1 -0
  118. package/server/models/constructor-items/common.d.ts +25 -0
  119. package/server/utils/blocks.d.ts +1 -1
  120. package/server/utils/common.d.ts +6 -0
  121. package/server/utils/common.js +24 -0
  122. package/server/utils/index.d.ts +1 -0
  123. package/server/utils/index.js +1 -0
  124. /package/build/cjs/{blocks/Media/MediaContent.d.ts → components/MediaBase/MediaBaseContent.d.ts} +0 -0
@@ -1,39 +1,15 @@
1
- import { __rest } from "tslib";
2
- import React, { useContext, useMemo, useState } from 'react';
3
- import { block, getThemedValue } from '../../utils';
4
- import { Grid, Row, Col, GridColumnSize } from '../../grid';
1
+ import React, { useContext, useState } from 'react';
2
+ import { getThemedValue } from '../../utils';
5
3
  import Media from '../../components/Media/Media';
6
- import AnimateBlock from '../../components/AnimateBlock/AnimateBlock';
7
- import BlockHeader from '../../components/BlockHeader/BlockHeader';
8
- import MediaContent from './MediaContent';
4
+ import MediaBase from '../../components/MediaBase/MediaBase';
9
5
  import { ThemeValueContext } from '../../context/theme/ThemeValueContext';
10
- import './Media.css';
11
- const b = block('media-block');
12
6
  export const MediaBlock = (props) => {
13
- const { media, largeMedia, direction = 'content-media', mobileDirection = 'content-media', animated, mediaOnly, disableShadow = false } = props, mediaContentProps = __rest(props, ["media", "largeMedia", "direction", "mobileDirection", "animated", "mediaOnly", "disableShadow"]);
14
- const { title, description } = mediaContentProps;
7
+ const { media } = props;
15
8
  const [play, setPlay] = useState(false);
16
9
  const { themeValue: theme } = useContext(ThemeValueContext);
17
10
  const mediaThemed = getThemedValue(media, theme);
18
- const mediaSizes = useMemo(() => {
19
- return mediaOnly
20
- ? { [GridColumnSize.All]: 12 }
21
- : { [GridColumnSize.Md]: largeMedia ? 8 : 6, [GridColumnSize.All]: 12 };
22
- }, [mediaOnly, largeMedia]);
23
- const contentSizes = useMemo(() => {
24
- return { [GridColumnSize.Md]: largeMedia ? 4 : 6, [GridColumnSize.All]: 12 };
25
- }, [largeMedia]);
26
- const mediaContent = !mediaOnly && React.createElement(MediaContent, Object.assign({}, mediaContentProps));
27
- return (React.createElement(AnimateBlock, { className: b(), onScroll: () => setPlay(true), animate: animated },
28
- mediaOnly && (React.createElement(BlockHeader, { className: b('header'), title: title, description: description })),
29
- React.createElement(Grid, null,
30
- React.createElement(Row, { className: b('row', {
31
- reverse: direction === 'media-content',
32
- 'mobile-reverse': mobileDirection === 'media-content',
33
- }) },
34
- React.createElement(Col, { className: b('content'), sizes: contentSizes }, mediaContent),
35
- React.createElement(Col, { sizes: mediaSizes },
36
- React.createElement("div", { className: b('card', { shadow: !disableShadow }) },
37
- React.createElement(Media, Object.assign({}, mediaThemed, { playVideo: play }))))))));
11
+ return (React.createElement(MediaBase, Object.assign({}, props, { onScroll: () => setPlay(true) }),
12
+ React.createElement(MediaBase.Card, null,
13
+ React.createElement(Media, Object.assign({}, mediaThemed, { playVideo: play })))));
38
14
  };
39
15
  export default MediaBlock;
@@ -133,32 +133,267 @@ export declare const Media: {
133
133
  };
134
134
  };
135
135
  };
136
- export declare const MediaBlock: {
137
- 'media-block': {
136
+ export declare const MediaBlockBaseProps: {
137
+ description: {
138
+ type: string;
139
+ contentType: string;
140
+ };
141
+ direction: {
142
+ type: string;
143
+ enum: string[];
144
+ };
145
+ mobileDirection: {
146
+ type: string;
147
+ enum: string[];
148
+ };
149
+ largeMedia: {
150
+ type: string;
151
+ };
152
+ mediaOnly: {
153
+ type: string;
154
+ };
155
+ disableShadow: {
156
+ type: string;
157
+ };
158
+ button: {
159
+ type: string;
138
160
  additionalProperties: boolean;
139
- required: string[];
140
161
  properties: {
141
- description: {
162
+ text: {
142
163
  type: string;
143
164
  contentType: string;
144
165
  };
145
- direction: {
166
+ url: {
167
+ type: string;
168
+ };
169
+ primary: {
170
+ type: string;
171
+ };
172
+ size: {
146
173
  type: string;
147
174
  enum: string[];
148
175
  };
149
- mobileDirection: {
176
+ theme: {
150
177
  type: string;
151
178
  enum: string[];
152
179
  };
153
- largeMedia: {
180
+ img: {
181
+ anyOf: ({
182
+ type: string;
183
+ additionalProperties?: undefined;
184
+ required?: undefined;
185
+ properties?: undefined;
186
+ } | {
187
+ type: string;
188
+ additionalProperties: boolean;
189
+ required: string[];
190
+ properties: {
191
+ data: {
192
+ type: string;
193
+ };
194
+ position: {
195
+ type: string;
196
+ enum: string[];
197
+ };
198
+ alt: {
199
+ type: string;
200
+ contentType: string;
201
+ };
202
+ };
203
+ })[];
204
+ };
205
+ metrikaGoals: {
206
+ anyOf: ({
207
+ type: string;
208
+ items?: undefined;
209
+ } | {
210
+ type: string;
211
+ items: {
212
+ type: string;
213
+ additionalProperties?: undefined;
214
+ required?: undefined;
215
+ properties?: undefined;
216
+ };
217
+ } | {
218
+ type: string;
219
+ items: {
220
+ type: string;
221
+ additionalProperties: boolean;
222
+ required: string[];
223
+ properties: {
224
+ name: {
225
+ type: string;
226
+ };
227
+ isCrossSite: {
228
+ type: string;
229
+ };
230
+ };
231
+ };
232
+ })[];
233
+ };
234
+ pixelEvents: {
235
+ type: string;
236
+ items: {
237
+ type: string;
238
+ required: string[];
239
+ additionalProperties: boolean;
240
+ properties: {
241
+ name: {
242
+ type: string;
243
+ enum: import("../..").PixelEventType[];
244
+ };
245
+ data: {};
246
+ };
247
+ select: {
248
+ $data: string;
249
+ };
250
+ selectCases: {
251
+ SubmitApplication: {
252
+ additionalProperties: boolean;
253
+ properties: {
254
+ name: {};
255
+ };
256
+ };
257
+ Contact: {
258
+ additionalProperties: boolean;
259
+ properties: {
260
+ name: {};
261
+ };
262
+ };
263
+ Lead: {
264
+ additionalProperties: boolean;
265
+ properties: {
266
+ name: {};
267
+ data: {
268
+ type: string;
269
+ additionalProperties: boolean;
270
+ properties: {
271
+ content_category: {
272
+ type: string;
273
+ };
274
+ content_name: {
275
+ type: string;
276
+ };
277
+ currency: {
278
+ type: string;
279
+ };
280
+ value: {
281
+ type: string;
282
+ };
283
+ };
284
+ };
285
+ };
286
+ };
287
+ };
288
+ };
289
+ };
290
+ target: {
154
291
  type: string;
292
+ enum: string[];
155
293
  };
156
- mediaOnly: {
294
+ };
295
+ if: {
296
+ properties: {
297
+ theme: {
298
+ enum: string[];
299
+ };
300
+ };
301
+ };
302
+ then: {
303
+ required: string[];
304
+ };
305
+ else: {
306
+ required: string[];
307
+ };
308
+ };
309
+ title: {
310
+ oneOf: ({
311
+ type: string;
312
+ additionalProperties: boolean;
313
+ required: string[];
314
+ properties: {
315
+ text: {
316
+ type: string;
317
+ contentType: string;
318
+ };
319
+ textSize: {
320
+ type: string;
321
+ enum: string[];
322
+ };
323
+ url: {
324
+ type: string;
325
+ };
326
+ resetMargin: {
327
+ type: string;
328
+ };
329
+ };
330
+ } | {
331
+ type: string;
332
+ contentType: string;
333
+ })[];
334
+ };
335
+ size: {
336
+ type: string;
337
+ enum: string[];
338
+ };
339
+ additionalInfo: {
340
+ type: string;
341
+ contentType: string;
342
+ };
343
+ links: {
344
+ type: string;
345
+ items: {
346
+ type: string;
347
+ properties: {
348
+ when: {
349
+ type: string;
350
+ };
351
+ };
352
+ };
353
+ };
354
+ buttons: {
355
+ type: string;
356
+ items: {
357
+ type: string;
358
+ properties: {
359
+ when: {
360
+ type: string;
361
+ };
362
+ };
363
+ };
364
+ };
365
+ animated: {
366
+ type: string;
367
+ };
368
+ anchor: {
369
+ type: string;
370
+ additionalProperties: boolean;
371
+ required: string[];
372
+ properties: {
373
+ text: {
157
374
  type: string;
375
+ contentType: string;
158
376
  };
159
- disableShadow: {
377
+ url: {
160
378
  type: string;
161
379
  };
380
+ };
381
+ };
382
+ visible: {
383
+ type: string;
384
+ enum: string[];
385
+ };
386
+ resetPaddings: {
387
+ type: string;
388
+ };
389
+ type: {};
390
+ when: {};
391
+ };
392
+ export declare const MediaBlock: {
393
+ 'media-block': {
394
+ additionalProperties: boolean;
395
+ required: string[];
396
+ properties: {
162
397
  media: {
163
398
  type: string;
164
399
  additionalProperties: boolean;
@@ -294,6 +529,27 @@ export declare const MediaBlock: {
294
529
  };
295
530
  };
296
531
  };
532
+ description: {
533
+ type: string;
534
+ contentType: string;
535
+ };
536
+ direction: {
537
+ type: string;
538
+ enum: string[];
539
+ };
540
+ mobileDirection: {
541
+ type: string;
542
+ enum: string[];
543
+ };
544
+ largeMedia: {
545
+ type: string;
546
+ };
547
+ mediaOnly: {
548
+ type: string;
549
+ };
550
+ disableShadow: {
551
+ type: string;
552
+ };
297
553
  button: {
298
554
  type: string;
299
555
  additionalProperties: boolean;
@@ -8,25 +8,26 @@ export const Media = {
8
8
  properties: MediaProps,
9
9
  };
10
10
  const MediaBlockContentProps = omit(ContentBase, ['text', 'theme']);
11
+ export const MediaBlockBaseProps = Object.assign(Object.assign(Object.assign(Object.assign({}, BlockBaseProps), AnimatableProps), MediaBlockContentProps), { description: {
12
+ type: 'string',
13
+ contentType: 'yfm',
14
+ }, direction: {
15
+ type: 'string',
16
+ enum: mediaDirection,
17
+ }, mobileDirection: {
18
+ type: 'string',
19
+ enum: mediaDirection,
20
+ }, largeMedia: {
21
+ type: 'boolean',
22
+ }, mediaOnly: {
23
+ type: 'boolean',
24
+ }, disableShadow: {
25
+ type: 'boolean',
26
+ }, button: ButtonBlock });
11
27
  export const MediaBlock = {
12
28
  'media-block': {
13
29
  additionalProperties: false,
14
30
  required: ['title', 'media'],
15
- properties: Object.assign(Object.assign(Object.assign(Object.assign({}, BlockBaseProps), AnimatableProps), MediaBlockContentProps), { description: {
16
- type: 'string',
17
- contentType: 'yfm',
18
- }, direction: {
19
- type: 'string',
20
- enum: mediaDirection,
21
- }, mobileDirection: {
22
- type: 'string',
23
- enum: mediaDirection,
24
- }, largeMedia: {
25
- type: 'boolean',
26
- }, mediaOnly: {
27
- type: 'boolean',
28
- }, disableShadow: {
29
- type: 'boolean',
30
- }, media: Media, button: ButtonBlock }),
31
+ properties: Object.assign(Object.assign({}, MediaBlockBaseProps), { media: Media }),
31
32
  },
32
33
  };
@@ -3,6 +3,7 @@ export { default as CompaniesBlock } from './Companies/Companies';
3
3
  export { default as SimpleBlock } from './Simple/Simple';
4
4
  export { default as InfoBlock } from './Info/Info';
5
5
  export { default as MediaBlock } from './Media/Media';
6
+ export { default as MapBlock } from './Map/Map';
6
7
  export { default as PreviewBlock } from './Preview/Preview';
7
8
  export { default as SecurityBlock } from './Security/Security';
8
9
  export { default as SliderBlock } from './Slider/Slider';
@@ -3,6 +3,7 @@ export { default as CompaniesBlock } from './Companies/Companies';
3
3
  export { default as SimpleBlock } from './Simple/Simple';
4
4
  export { default as InfoBlock } from './Info/Info';
5
5
  export { default as MediaBlock } from './Media/Media';
6
+ export { default as MapBlock } from './Map/Map';
6
7
  export { default as PreviewBlock } from './Preview/Preview';
7
8
  export { default as SecurityBlock } from './Security/Security';
8
9
  export { default as SliderBlock } from './Slider/Slider';
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { GMapProps } from '../../models';
3
+ declare const GoogleMap: React.FC<GMapProps>;
4
+ export default GoogleMap;
@@ -0,0 +1,39 @@
1
+ import React, { useContext, useEffect, useRef, useState, useMemo } from 'react';
2
+ import _ from 'lodash';
3
+ import { block } from '../../utils';
4
+ import { MapsContext } from '../../context/mapsContext/mapsContext';
5
+ import { LocaleContext } from '../../context/localeContext/localeContext';
6
+ import { MobileContext } from '../../context/mobileContext';
7
+ import { getMapHeight } from './helpers';
8
+ const b = block('map');
9
+ function getScriptSrc(apiKey, scriptSrc, address, lang) {
10
+ return `${scriptSrc}?key=${apiKey}&language=${lang}&q=${encodeURI(address)}`;
11
+ }
12
+ const GoogleMap = (props) => {
13
+ const { address } = props;
14
+ const { apiKey, scriptSrc } = useContext(MapsContext);
15
+ const { lang = 'ru' } = useContext(LocaleContext);
16
+ const isMobile = useContext(MobileContext);
17
+ const [height, setHeight] = useState(undefined);
18
+ const ref = useRef(null);
19
+ const src = useMemo(() => getScriptSrc(apiKey, scriptSrc, address, lang), [apiKey, scriptSrc, address, lang]);
20
+ useEffect(() => {
21
+ const updateSize = _.debounce(() => {
22
+ if (ref.current) {
23
+ setHeight(Math.round(getMapHeight(ref.current.offsetWidth, isMobile)));
24
+ }
25
+ }, 100);
26
+ updateSize();
27
+ window.addEventListener('resize', updateSize);
28
+ return () => {
29
+ window.removeEventListener('resize', updateSize);
30
+ };
31
+ }, [isMobile]);
32
+ if (!apiKey || !address) {
33
+ return null;
34
+ }
35
+ return (React.createElement("iframe", { className: b(), ref: ref, style: {
36
+ height,
37
+ }, loading: "lazy", allowFullScreen: true, referrerPolicy: "no-referrer-when-downgrade", src: src }));
38
+ };
39
+ export default GoogleMap;
@@ -0,0 +1,20 @@
1
+ /* use this for style redefinitions to awoid problems with
2
+ unpredictable css rules order in build */
3
+ .pc-map {
4
+ width: 100%;
5
+ height: 300px;
6
+ border: 0;
7
+ overflow: hidden;
8
+ display: flex;
9
+ }
10
+ .pc-map__spinner {
11
+ margin: 0 auto;
12
+ align-self: center;
13
+ }
14
+ .pc-map__wrapper {
15
+ min-height: 300px;
16
+ display: flex;
17
+ flex-direction: column;
18
+ align-items: center;
19
+ justify-content: center;
20
+ }
@@ -0,0 +1,4 @@
1
+ import { MapProps } from '../../models';
2
+ import './Map.css';
3
+ export declare const Map: (props: MapProps) => JSX.Element | null;
4
+ export default Map;
@@ -0,0 +1,17 @@
1
+ import React, { useContext } from 'react';
2
+ import { MapsContext, MapType } from '../../context/mapsContext/mapsContext';
3
+ import YandexMap from './YMap/YandexMap';
4
+ import GoogleMap from './GoogleMap';
5
+ import './Map.css';
6
+ export const Map = (props) => {
7
+ const { type } = useContext(MapsContext);
8
+ switch (type) {
9
+ case MapType.Yandex:
10
+ return React.createElement(YandexMap, Object.assign({}, props));
11
+ case MapType.Google:
12
+ return React.createElement(GoogleMap, Object.assign({}, props));
13
+ default:
14
+ return null;
15
+ }
16
+ };
17
+ export default Map;
@@ -0,0 +1,13 @@
1
+ import { YMapMarker } from '../../../models';
2
+ export declare class YMap {
3
+ private ymap;
4
+ private mapRef;
5
+ private coords;
6
+ constructor(ymap: Ymaps.Map, mapRef: HTMLDivElement | null);
7
+ showPlacemarks(markers: YMapMarker[]): Promise<void>;
8
+ findAddress(marker: YMapMarker): Promise<void>;
9
+ findCoordinate(marker: YMapMarker): void;
10
+ private drawPlaceMarkStyle;
11
+ private recalcZoomAndCenter;
12
+ private clearOldPlacemarks;
13
+ }
@@ -0,0 +1,93 @@
1
+ var GeoObjectTypes;
2
+ (function (GeoObjectTypes) {
3
+ GeoObjectTypes["Properties"] = "properties";
4
+ GeoObjectTypes["Options"] = "options";
5
+ })(GeoObjectTypes || (GeoObjectTypes = {}));
6
+ const DEFAULT_PLACEMARKS_COLOR = '#dc534b';
7
+ // presetStorage: https://yandex.com/dev/maps/jsapi/doc/2.1/ref/reference/option.presetStorage.html
8
+ const DEFAULT_PLACEMARKS_PRESET = 'islands#dotIcon';
9
+ const DEFAULT_MAP_CONTROL_BUTTON_HEIGHT = 30;
10
+ const geoObjectPropsAndOptions = {
11
+ iconCaption: GeoObjectTypes.Properties,
12
+ iconContent: GeoObjectTypes.Properties,
13
+ iconColor: GeoObjectTypes.Options,
14
+ preset: GeoObjectTypes.Options,
15
+ };
16
+ export class YMap {
17
+ constructor(ymap, mapRef) {
18
+ this.coords = [];
19
+ this.ymap = ymap;
20
+ this.mapRef = mapRef;
21
+ }
22
+ async showPlacemarks(markers) {
23
+ this.clearOldPlacemarks();
24
+ for (const marker of markers) {
25
+ if (marker.address) {
26
+ await this.findAddress(marker);
27
+ }
28
+ else if (marker.coordinate) {
29
+ this.findCoordinate(marker);
30
+ }
31
+ }
32
+ this.recalcZoomAndCenter();
33
+ }
34
+ async findAddress(marker) {
35
+ try {
36
+ const res = await window.ymaps.geocode(marker.address, { results: 1 });
37
+ const geoObject = res.geoObjects.get(0);
38
+ const coordinate = geoObject.geometry.getCoordinates();
39
+ this.coords.push(coordinate);
40
+ this.drawPlaceMarkStyle(geoObject, marker);
41
+ this.ymap.geoObjects.add(geoObject);
42
+ }
43
+ catch (_a) { } // If error - placemark will not be displayed
44
+ }
45
+ findCoordinate(marker) {
46
+ const geoObject = new window.ymaps.Placemark(marker.coordinate, {});
47
+ this.coords.push(marker.coordinate);
48
+ this.drawPlaceMarkStyle(geoObject, marker);
49
+ this.ymap.geoObjects.add(geoObject);
50
+ }
51
+ drawPlaceMarkStyle(geoObject, marker) {
52
+ if (!marker.label) {
53
+ return;
54
+ }
55
+ const { iconColor, preset = DEFAULT_PLACEMARKS_PRESET } = marker.label;
56
+ let localIconColor = iconColor;
57
+ // You can set the preset option together with the iconColor option only if it not a 'Stretchy' preset
58
+ if (!preset.includes('Stretchy') && !iconColor) {
59
+ localIconColor = DEFAULT_PLACEMARKS_COLOR;
60
+ }
61
+ Object.entries(Object.assign(Object.assign({}, marker.label), { iconColor: localIconColor, preset })).forEach(([key, value]) => {
62
+ const geoObjectParamType = geoObjectPropsAndOptions[key];
63
+ if (value && geoObjectParamType) {
64
+ geoObject[geoObjectParamType].set(key, value);
65
+ }
66
+ });
67
+ }
68
+ recalcZoomAndCenter() {
69
+ var _a, _b;
70
+ const coordsLength = this.coords.length;
71
+ if (!coordsLength) {
72
+ return;
73
+ }
74
+ let leftBottom = [Infinity, Infinity], rightTop = [-Infinity, -Infinity];
75
+ this.coords.forEach((point) => {
76
+ leftBottom = [Math.min(leftBottom[0], point[0]), Math.min(leftBottom[1], point[1])];
77
+ rightTop = [Math.max(rightTop[0], point[0]), Math.max(rightTop[1], point[1])];
78
+ });
79
+ const newMapParams = window.ymaps.util.bounds.getCenterAndZoom([leftBottom, rightTop], [(_a = this.mapRef) === null || _a === void 0 ? void 0 : _a.clientWidth, (_b = this.mapRef) === null || _b === void 0 ? void 0 : _b.clientHeight], undefined, { margin: DEFAULT_MAP_CONTROL_BUTTON_HEIGHT });
80
+ this.ymap.setCenter(newMapParams.center);
81
+ // Use default zoom for one placemark
82
+ if (coordsLength > 1) {
83
+ this.ymap.setZoom(newMapParams.zoom);
84
+ }
85
+ }
86
+ clearOldPlacemarks() {
87
+ if (this.coords.length === 0) {
88
+ return;
89
+ }
90
+ this.ymap.geoObjects.removeAll();
91
+ this.coords = [];
92
+ }
93
+ }
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { YMapProps } from '../../../models';
3
+ declare const YandexMap: React.FC<YMapProps>;
4
+ export default YandexMap;