@redneckz/wildless-cms-uni-blocks 0.6.41 → 0.6.42

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 (233) hide show
  1. package/bundle/blocks.schema.json +1 -1
  2. package/bundle/bundle.umd.js +130 -32
  3. package/bundle/bundle.umd.min.js +1 -1
  4. package/bundle/components/CarouselRecommendationCard/CarouselRecommendationCard.d.ts +5 -0
  5. package/bundle/components/CarouselRecommendationCard/CarouselRecommendationCardContent.d.ts +44 -0
  6. package/bundle/components/Header/HeaderSecondaryMenu.d.ts +2 -0
  7. package/bundle/hooks/useCachedAsyncData.d.ts +2 -0
  8. package/bundle/hooks/useLocation.d.ts +6 -0
  9. package/bundle/hooks/useRegions.d.ts +6 -0
  10. package/bundle/services/sitemap/SitemapProps.d.ts +8 -0
  11. package/bundle/ui-kit/Location/Location.d.ts +19 -0
  12. package/bundle/ui-kit/Location/SearchBar.d.ts +6 -0
  13. package/bundle/utils/groupBy.d.ts +1 -0
  14. package/dist/components/Blocks.js +4 -2
  15. package/dist/components/Blocks.js.map +1 -1
  16. package/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.d.ts +5 -0
  17. package/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.js +22 -0
  18. package/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.js.map +1 -0
  19. package/dist/components/CarouselRecommendationCard/CarouselRecommendationCardContent.d.ts +44 -0
  20. package/dist/components/CarouselRecommendationCard/CarouselRecommendationCardContent.js +2 -0
  21. package/dist/components/CarouselRecommendationCard/CarouselRecommendationCardContent.js.map +1 -0
  22. package/dist/components/Header/Header.js +2 -2
  23. package/dist/components/Header/Header.js.map +1 -1
  24. package/dist/components/Header/HeaderBurger.js +4 -3
  25. package/dist/components/Header/HeaderBurger.js.map +1 -1
  26. package/dist/components/Header/HeaderSecondaryMenu.d.ts +2 -0
  27. package/dist/components/Header/HeaderSecondaryMenu.js +13 -4
  28. package/dist/components/Header/HeaderSecondaryMenu.js.map +1 -1
  29. package/dist/components/Recommendation/RecommendationCard.js +1 -1
  30. package/dist/components/Recommendation/RecommendationCard.js.map +1 -1
  31. package/dist/hooks/useCachedAsyncData.d.ts +2 -0
  32. package/dist/hooks/useCachedAsyncData.js +25 -0
  33. package/dist/hooks/useCachedAsyncData.js.map +1 -0
  34. package/dist/hooks/useLocation.d.ts +6 -0
  35. package/dist/hooks/useLocation.js +26 -0
  36. package/dist/hooks/useLocation.js.map +1 -0
  37. package/dist/hooks/useRegions.d.ts +6 -0
  38. package/dist/hooks/useRegions.js +11 -0
  39. package/dist/hooks/useRegions.js.map +1 -0
  40. package/dist/services/sitemap/SitemapProps.d.ts +8 -0
  41. package/dist/ui-kit/Location/Location.d.ts +19 -0
  42. package/dist/ui-kit/Location/Location.js +44 -0
  43. package/dist/ui-kit/Location/Location.js.map +1 -0
  44. package/dist/ui-kit/Location/SearchBar.d.ts +6 -0
  45. package/dist/ui-kit/Location/SearchBar.js +9 -0
  46. package/dist/ui-kit/Location/SearchBar.js.map +1 -0
  47. package/dist/ui-kit/SwipeListControl/SwipeListContainer.js +8 -4
  48. package/dist/ui-kit/SwipeListControl/SwipeListContainer.js.map +1 -1
  49. package/dist/utils/groupBy.d.ts +1 -0
  50. package/dist/utils/groupBy.js +13 -0
  51. package/dist/utils/groupBy.js.map +1 -0
  52. package/lib/common.css +1 -1
  53. package/lib/components/Blocks.js +4 -2
  54. package/lib/components/Blocks.js.map +1 -1
  55. package/lib/components/Carousel/Carousel.fixture.d.ts +1 -0
  56. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.d.ts +5 -0
  57. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.fixture.d.ts +9 -0
  58. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.js +20 -0
  59. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.js.map +1 -0
  60. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCardContent.d.ts +44 -0
  61. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCardContent.js +2 -0
  62. package/lib/components/CarouselRecommendationCard/CarouselRecommendationCardContent.js.map +1 -0
  63. package/lib/components/Header/Header.js +2 -2
  64. package/lib/components/Header/Header.js.map +1 -1
  65. package/lib/components/Header/HeaderBurger.js +4 -3
  66. package/lib/components/Header/HeaderBurger.js.map +1 -1
  67. package/lib/components/Header/HeaderSecondaryMenu.d.ts +2 -0
  68. package/lib/components/Header/HeaderSecondaryMenu.js +13 -4
  69. package/lib/components/Header/HeaderSecondaryMenu.js.map +1 -1
  70. package/lib/components/Recommendation/Recommendation.fixture.d.ts +1 -1
  71. package/lib/components/Recommendation/RecommendationCard.js +1 -1
  72. package/lib/components/Recommendation/RecommendationCard.js.map +1 -1
  73. package/lib/hooks/useCachedAsyncData.d.ts +2 -0
  74. package/lib/hooks/useCachedAsyncData.js +22 -0
  75. package/lib/hooks/useCachedAsyncData.js.map +1 -0
  76. package/lib/hooks/useLocation.d.ts +6 -0
  77. package/lib/hooks/useLocation.js +23 -0
  78. package/lib/hooks/useLocation.js.map +1 -0
  79. package/lib/hooks/useRegions.d.ts +6 -0
  80. package/lib/hooks/useRegions.js +8 -0
  81. package/lib/hooks/useRegions.js.map +1 -0
  82. package/lib/services/sitemap/SitemapProps.d.ts +8 -0
  83. package/lib/ui-kit/Location/Location.d.ts +19 -0
  84. package/lib/ui-kit/Location/Location.fixture.d.ts +6 -0
  85. package/lib/ui-kit/Location/Location.js +42 -0
  86. package/lib/ui-kit/Location/Location.js.map +1 -0
  87. package/lib/ui-kit/Location/SearchBar.d.ts +6 -0
  88. package/lib/ui-kit/Location/SearchBar.js +7 -0
  89. package/lib/ui-kit/Location/SearchBar.js.map +1 -0
  90. package/lib/ui-kit/SwipeListControl/SwipeListContainer.js +8 -4
  91. package/lib/ui-kit/SwipeListControl/SwipeListContainer.js.map +1 -1
  92. package/lib/utils/groupBy.d.ts +1 -0
  93. package/lib/utils/groupBy.js +10 -0
  94. package/lib/utils/groupBy.js.map +1 -0
  95. package/mobile/bundle/bundle.umd.js +48 -20
  96. package/mobile/bundle/bundle.umd.min.js +1 -1
  97. package/mobile/bundle/components/CarouselRecommendationCard/CarouselRecommendationCard.d.ts +5 -0
  98. package/mobile/bundle/components/CarouselRecommendationCard/CarouselRecommendationCardContent.d.ts +44 -0
  99. package/mobile/bundle/components/Header/HeaderSecondaryMenu.d.ts +2 -0
  100. package/mobile/bundle/hooks/useCachedAsyncData.d.ts +2 -0
  101. package/mobile/bundle/hooks/useLocation.d.ts +6 -0
  102. package/mobile/bundle/hooks/useRegions.d.ts +6 -0
  103. package/mobile/bundle/services/sitemap/SitemapProps.d.ts +8 -0
  104. package/mobile/bundle/ui-kit/Location/Location.d.ts +19 -0
  105. package/mobile/bundle/ui-kit/Location/SearchBar.d.ts +6 -0
  106. package/mobile/bundle/utils/groupBy.d.ts +1 -0
  107. package/mobile/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.d.ts +5 -0
  108. package/mobile/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.js +22 -0
  109. package/mobile/dist/components/CarouselRecommendationCard/CarouselRecommendationCard.js.map +1 -0
  110. package/mobile/dist/components/CarouselRecommendationCard/CarouselRecommendationCardContent.d.ts +44 -0
  111. package/mobile/dist/components/CarouselRecommendationCard/CarouselRecommendationCardContent.js +2 -0
  112. package/mobile/dist/components/CarouselRecommendationCard/CarouselRecommendationCardContent.js.map +1 -0
  113. package/mobile/dist/components/Header/HeaderBurger.js +4 -3
  114. package/mobile/dist/components/Header/HeaderBurger.js.map +1 -1
  115. package/mobile/dist/components/Header/HeaderSecondaryMenu.d.ts +2 -0
  116. package/mobile/dist/components/Header/HeaderSecondaryMenu.js +13 -4
  117. package/mobile/dist/components/Header/HeaderSecondaryMenu.js.map +1 -1
  118. package/mobile/dist/components/Recommendation/RecommendationCard.js +1 -1
  119. package/mobile/dist/components/Recommendation/RecommendationCard.js.map +1 -1
  120. package/mobile/dist/hooks/useCachedAsyncData.d.ts +2 -0
  121. package/mobile/dist/hooks/useCachedAsyncData.js +25 -0
  122. package/mobile/dist/hooks/useCachedAsyncData.js.map +1 -0
  123. package/mobile/dist/hooks/useLocation.d.ts +6 -0
  124. package/mobile/dist/hooks/useLocation.js +26 -0
  125. package/mobile/dist/hooks/useLocation.js.map +1 -0
  126. package/mobile/dist/hooks/useRegions.d.ts +6 -0
  127. package/mobile/dist/hooks/useRegions.js +11 -0
  128. package/mobile/dist/hooks/useRegions.js.map +1 -0
  129. package/mobile/dist/services/sitemap/SitemapProps.d.ts +8 -0
  130. package/mobile/dist/ui-kit/Location/Location.d.ts +19 -0
  131. package/mobile/dist/ui-kit/Location/Location.js +44 -0
  132. package/mobile/dist/ui-kit/Location/Location.js.map +1 -0
  133. package/mobile/dist/ui-kit/Location/SearchBar.d.ts +6 -0
  134. package/mobile/dist/ui-kit/Location/SearchBar.js +9 -0
  135. package/mobile/dist/ui-kit/Location/SearchBar.js.map +1 -0
  136. package/mobile/dist/ui-kit/SwipeListControl/SwipeListContainer.js +8 -4
  137. package/mobile/dist/ui-kit/SwipeListControl/SwipeListContainer.js.map +1 -1
  138. package/mobile/dist/utils/groupBy.d.ts +1 -0
  139. package/mobile/dist/utils/groupBy.js +13 -0
  140. package/mobile/dist/utils/groupBy.js.map +1 -0
  141. package/mobile/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.d.ts +5 -0
  142. package/mobile/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.js +20 -0
  143. package/mobile/lib/components/CarouselRecommendationCard/CarouselRecommendationCard.js.map +1 -0
  144. package/mobile/lib/components/CarouselRecommendationCard/CarouselRecommendationCardContent.d.ts +44 -0
  145. package/mobile/lib/components/CarouselRecommendationCard/CarouselRecommendationCardContent.js +2 -0
  146. package/mobile/lib/components/CarouselRecommendationCard/CarouselRecommendationCardContent.js.map +1 -0
  147. package/mobile/lib/components/Header/HeaderBurger.js +4 -3
  148. package/mobile/lib/components/Header/HeaderBurger.js.map +1 -1
  149. package/mobile/lib/components/Header/HeaderSecondaryMenu.d.ts +2 -0
  150. package/mobile/lib/components/Header/HeaderSecondaryMenu.js +13 -4
  151. package/mobile/lib/components/Header/HeaderSecondaryMenu.js.map +1 -1
  152. package/mobile/lib/components/Recommendation/RecommendationCard.js +1 -1
  153. package/mobile/lib/components/Recommendation/RecommendationCard.js.map +1 -1
  154. package/mobile/lib/hooks/useCachedAsyncData.d.ts +2 -0
  155. package/mobile/lib/hooks/useCachedAsyncData.js +22 -0
  156. package/mobile/lib/hooks/useCachedAsyncData.js.map +1 -0
  157. package/mobile/lib/hooks/useLocation.d.ts +6 -0
  158. package/mobile/lib/hooks/useLocation.js +23 -0
  159. package/mobile/lib/hooks/useLocation.js.map +1 -0
  160. package/mobile/lib/hooks/useRegions.d.ts +6 -0
  161. package/mobile/lib/hooks/useRegions.js +8 -0
  162. package/mobile/lib/hooks/useRegions.js.map +1 -0
  163. package/mobile/lib/services/sitemap/SitemapProps.d.ts +8 -0
  164. package/mobile/lib/ui-kit/Location/Location.d.ts +19 -0
  165. package/mobile/lib/ui-kit/Location/Location.js +42 -0
  166. package/mobile/lib/ui-kit/Location/Location.js.map +1 -0
  167. package/mobile/lib/ui-kit/Location/SearchBar.d.ts +6 -0
  168. package/mobile/lib/ui-kit/Location/SearchBar.js +7 -0
  169. package/mobile/lib/ui-kit/Location/SearchBar.js.map +1 -0
  170. package/mobile/lib/ui-kit/SwipeListControl/SwipeListContainer.js +8 -4
  171. package/mobile/lib/ui-kit/SwipeListControl/SwipeListContainer.js.map +1 -1
  172. package/mobile/lib/utils/groupBy.d.ts +1 -0
  173. package/mobile/lib/utils/groupBy.js +10 -0
  174. package/mobile/lib/utils/groupBy.js.map +1 -0
  175. package/mobile/src/components/CarouselRecommendationCard/CarouselRecommendationCard.example.json +19 -0
  176. package/mobile/src/components/CarouselRecommendationCard/CarouselRecommendationCard.tsx +62 -0
  177. package/mobile/src/components/CarouselRecommendationCard/CarouselRecommendationCard.ui.json +9 -0
  178. package/mobile/src/components/CarouselRecommendationCard/CarouselRecommendationCardContent.ts +45 -0
  179. package/mobile/src/components/Header/HeaderBurger.tsx +5 -7
  180. package/mobile/src/components/Header/HeaderSecondaryMenu.tsx +32 -5
  181. package/mobile/src/components/MiniGallery/MiniGallery.ui.json +1 -1
  182. package/mobile/src/components/Recommendation/Recommendation.example.json +6 -5
  183. package/mobile/src/components/Recommendation/Recommendation.ui.json +8 -0
  184. package/mobile/src/components/Recommendation/RecommendationCard.tsx +1 -1
  185. package/mobile/src/hooks/useCachedAsyncData.ts +37 -0
  186. package/mobile/src/hooks/useLocation.ts +48 -0
  187. package/mobile/src/hooks/useRegions.ts +16 -0
  188. package/mobile/src/services/sitemap/SitemapProps.ts +9 -0
  189. package/mobile/src/ui-kit/Location/Location.tsx +168 -0
  190. package/mobile/src/ui-kit/Location/SearchBar.tsx +30 -0
  191. package/mobile/src/ui-kit/SwipeListControl/SwipeListContainer.tsx +8 -4
  192. package/mobile/src/utils/groupBy.ts +10 -0
  193. package/package.json +2 -2
  194. package/src/components/Blocks.ts +4 -2
  195. package/src/components/Carousel/Carousel.fixture.tsx +22 -4
  196. package/src/components/CarouselRecommendationCard/CarouselRecommendationCard.example.json +19 -0
  197. package/src/components/CarouselRecommendationCard/CarouselRecommendationCard.fixture.tsx +47 -0
  198. package/src/components/CarouselRecommendationCard/CarouselRecommendationCard.tsx +62 -0
  199. package/src/components/CarouselRecommendationCard/CarouselRecommendationCard.ui.json +9 -0
  200. package/src/components/CarouselRecommendationCard/CarouselRecommendationCardContent.ts +45 -0
  201. package/src/components/Header/Header.tsx +6 -4
  202. package/src/components/Header/HeaderBurger.tsx +5 -7
  203. package/src/components/Header/HeaderSecondaryMenu.tsx +32 -5
  204. package/src/components/MiniGallery/MiniGallery.ui.json +1 -1
  205. package/src/components/Recommendation/Recommendation.example.json +6 -5
  206. package/src/components/Recommendation/Recommendation.fixture.tsx +11 -10
  207. package/src/components/Recommendation/Recommendation.ui.json +8 -0
  208. package/src/components/Recommendation/RecommendationCard.tsx +1 -1
  209. package/src/hooks/useCachedAsyncData.ts +37 -0
  210. package/src/hooks/useLocation.ts +48 -0
  211. package/src/hooks/useRegions.ts +16 -0
  212. package/src/services/sitemap/SitemapProps.ts +9 -0
  213. package/src/ui-kit/Location/Location.fixture.tsx +81 -0
  214. package/src/ui-kit/Location/Location.tsx +168 -0
  215. package/src/ui-kit/Location/SearchBar.tsx +30 -0
  216. package/src/ui-kit/SwipeListControl/SwipeListContainer.tsx +8 -4
  217. package/src/utils/groupBy.ts +10 -0
  218. package/bundle/hooks/useGeolocation.d.ts +0 -1
  219. package/dist/hooks/useGeolocation.d.ts +0 -1
  220. package/dist/hooks/useGeolocation.js +0 -21
  221. package/dist/hooks/useGeolocation.js.map +0 -1
  222. package/lib/hooks/useGeolocation.d.ts +0 -1
  223. package/lib/hooks/useGeolocation.js +0 -18
  224. package/lib/hooks/useGeolocation.js.map +0 -1
  225. package/mobile/bundle/hooks/useGeolocation.d.ts +0 -1
  226. package/mobile/dist/hooks/useGeolocation.d.ts +0 -1
  227. package/mobile/dist/hooks/useGeolocation.js +0 -21
  228. package/mobile/dist/hooks/useGeolocation.js.map +0 -1
  229. package/mobile/lib/hooks/useGeolocation.d.ts +0 -1
  230. package/mobile/lib/hooks/useGeolocation.js +0 -18
  231. package/mobile/lib/hooks/useGeolocation.js.map +0 -1
  232. package/mobile/src/hooks/useGeolocation.ts +0 -22
  233. package/src/hooks/useGeolocation.ts +0 -22
@@ -0,0 +1,16 @@
1
+ import { useAsyncData } from '@redneckz/uni-jsx/lib/hooks/useAsyncData';
2
+ import { fetchJSONUnsafe } from '../utils/fetchJSON';
3
+
4
+ const REGIONS_URL = '/api/v1/regions';
5
+
6
+ export interface Region {
7
+ id?: number;
8
+ code?: string;
9
+ name?: string;
10
+ }
11
+
12
+ export function useRegions(): Region[] {
13
+ const { data } = useAsyncData<Region[]>(REGIONS_URL, fetchJSONUnsafe);
14
+
15
+ return data || [];
16
+ }
@@ -20,10 +20,19 @@ export interface DispositionItem extends LinkProps {
20
20
  icon?: Picture;
21
21
  }
22
22
 
23
+ /**
24
+ * @title Представительства за рубежом
25
+ * @required ["text", "href"]
26
+ */
27
+ export interface ForeignOffice extends LinkProps {
28
+ icon?: Picture;
29
+ }
30
+
23
31
  export interface SitemapDataProps {
24
32
  topItems?: TopMenuItem[];
25
33
  dispositions?: DispositionItem[];
26
34
  logo?: LogoType;
35
+ foreignOffices?: ForeignOffice[];
27
36
  defaultLocation?: string;
28
37
  officesLink?: string;
29
38
  }
@@ -0,0 +1,168 @@
1
+ import { JSX } from '@redneckz/uni-jsx';
2
+ import { useCallback } from '@redneckz/uni-jsx/lib/hooks';
3
+ import { useLink } from '../../hooks/useLink';
4
+ import type { Region } from '../../hooks/useRegions';
5
+ import { useRegions } from '../../hooks/useRegions';
6
+ import { useSearch } from '../../hooks/useSearch';
7
+ import type { UniBlockProps } from '../../model/JSXBlock';
8
+ import type { ForeignOffice } from '../../services/sitemap/SitemapProps';
9
+ import { Text } from '../../ui-kit/Text/Text';
10
+ import { groupBy } from '../../utils/groupBy';
11
+ import { Img } from '../Img/Img';
12
+ import { SearchBar } from './SearchBar';
13
+
14
+ const SEARCH_TERM_MIN_LENGTH = 3;
15
+
16
+ interface RegionLinkProps {
17
+ onChangeLocation?: (region: Region) => void;
18
+ }
19
+
20
+ interface CloseButtonProps {
21
+ close?: () => void;
22
+ }
23
+
24
+ interface CurrentLocationProps {
25
+ currentLocation?: Region;
26
+ }
27
+
28
+ interface ForeignOfficeProps {
29
+ foreignOffices?: ForeignOffice[];
30
+ }
31
+
32
+ export type LocationProps = ForeignOfficeProps &
33
+ CloseButtonProps &
34
+ RegionLinkProps &
35
+ CurrentLocationProps &
36
+ UniBlockProps;
37
+
38
+ export const Location = JSX<LocationProps>(
39
+ ({ currentLocation, onChangeLocation, close, foreignOffices }) => {
40
+ const { term, setTerm } = useSearch();
41
+
42
+ const handleSearch = useCallback((_: string) => setTerm(_), []);
43
+
44
+ const regions: Region[] = cleanUpRegions(useRegions()).sort((a, b) =>
45
+ a.name.localeCompare(b.name),
46
+ );
47
+ const regionsGroupByLetter: Map<string, Region[]> = groupBy(regions, regionFirstLetter);
48
+
49
+ return (
50
+ <div className="absolute h-full w-full inset-0 bg-white text-l-light z-50">
51
+ <CloseButton close={close} />
52
+ <div className="container py-12">
53
+ <CurrentLocation currentLocation={currentLocation} />
54
+ <SearchBar onSearch={handleSearch} searchTerm={term} className="mb-7" />
55
+
56
+ {term && term.length >= SEARCH_TERM_MIN_LENGTH ? (
57
+ <div>
58
+ {regions
59
+ .filter((region) => region.name?.startsWith(term))
60
+ .map(renderRegion({ onChangeLocation, close }))}
61
+ </div>
62
+ ) : (
63
+ <div className="columns-5">
64
+ {Array.from(regionsGroupByLetter.entries()).map(
65
+ renderRegionGroup({ onChangeLocation, close }),
66
+ )}
67
+ </div>
68
+ )}
69
+
70
+ <ForeignOffices foreignOffices={foreignOffices} />
71
+ </div>
72
+ </div>
73
+ );
74
+ },
75
+ );
76
+
77
+ const regionFirstLetter = (region: Region) => region.name?.charAt(0) || '';
78
+
79
+ const cleanUpRegions = (regions: Region[]) =>
80
+ regions.map((region) => ({
81
+ ...region,
82
+ name: region.name?.replace(/республика|область|край'/gi, '').trim() || '',
83
+ }));
84
+
85
+ const CurrentLocation = JSX<CurrentLocationProps>(({ currentLocation }) =>
86
+ currentLocation ? (
87
+ <div className="mb-4">
88
+ <Text size="text-l" font="font-light">
89
+ Сейчас выбран:&nbsp;
90
+ </Text>
91
+ <button className="cursor-pointer" onClick={close}>
92
+ <Text color="text-green">{currentLocation.name}</Text>
93
+ </button>
94
+ </div>
95
+ ) : null,
96
+ );
97
+
98
+ const CloseButton = JSX<CloseButtonProps>(({ close }) => (
99
+ <button
100
+ className="visible peer-placeholder-shown:invisible absolute top-6 right-6 w-6 h-6 p-1 bg-transparent cursor-pointer border-none"
101
+ onClick={(e) => {
102
+ e.preventDefault();
103
+ close && close();
104
+ }}
105
+ >
106
+ <Img image="CloseIcon" width="24" height="24" />
107
+ </button>
108
+ ));
109
+
110
+ const renderRegionGroup =
111
+ ({ onChangeLocation, close }: RegionLinkProps & CloseButtonProps) =>
112
+ ([letter, regions]: [string, Region[]]) =>
113
+ (
114
+ <div key={letter} className="break-inside-avoid mb-7 w-[224px]">
115
+ <div className="mb-2.5">
116
+ <Text size="text-h6">{letter}</Text>
117
+ </div>
118
+ {regions.map(renderRegion({ onChangeLocation, close }))}
119
+ </div>
120
+ );
121
+
122
+ const renderRegion =
123
+ ({ onChangeLocation, close }: RegionLinkProps & CloseButtonProps) =>
124
+ (region: Region) =>
125
+ (
126
+ <div key={region.id} className="mb-1">
127
+ <button
128
+ className="cursor-pointer hover:text-primary-hover"
129
+ onClick={() => {
130
+ onChangeLocation && onChangeLocation(region);
131
+ close && close();
132
+ }}
133
+ >
134
+ {region.name}
135
+ </button>
136
+ </div>
137
+ );
138
+
139
+ const ForeignOffices = JSX<ForeignOfficeProps>(({ foreignOffices }) =>
140
+ foreignOffices?.length ? (
141
+ <div className="border-t border-main-divider mt-7 pt-7">
142
+ <div className="mb-4">
143
+ <Text size="text-m-light" color="text-secondary-text">
144
+ Представительства за рубежом:
145
+ </Text>
146
+ </div>
147
+ <div className="flex gap-10">
148
+ {foreignOffices.map((office, i: number) => (
149
+ <ForeignOffice key={String(i)} {...office} />
150
+ ))}
151
+ </div>
152
+ </div>
153
+ ) : null,
154
+ );
155
+
156
+ const ForeignOffice = JSX<ForeignOffice>(({ icon, ...rest }) => {
157
+ const link = useLink();
158
+ const { text, target, href, onClick } = link(rest);
159
+
160
+ return (
161
+ <div className="flex gap-x-3">
162
+ <Img image={icon} />
163
+ <a className="hover:text-primary-hover" href={href} target={target} onClick={onClick}>
164
+ {text}
165
+ </a>
166
+ </div>
167
+ );
168
+ });
@@ -0,0 +1,30 @@
1
+ import { JSX } from '@redneckz/uni-jsx';
2
+
3
+ export interface SearchBarInnerProps {
4
+ className?: string;
5
+ searchTerm?: string;
6
+ onSearch: (_: string) => void;
7
+ }
8
+
9
+ export const SearchBar = JSX<SearchBarInnerProps>(({ className, searchTerm, onSearch }) => {
10
+ return (
11
+ <form className={`font-sans relative ${className}`}>
12
+ <div className="absolute rounded h-full flex items-center justify-center pl-4 max-w-[170px] gap-3.5 pointer-events-none">
13
+ {searchTerm ? null : (
14
+ <label htmlFor="search-bar-input" className={`text-secondary-text `}>
15
+ Поиск по филиалам
16
+ </label>
17
+ )}
18
+ </div>
19
+ <input
20
+ id="search-bar-input"
21
+ className={`h-12 pl-4 w-full peer text-l text-black border border-solid rounded-md box-border
22
+ outline-none border-main-stroke hover:border-primary-hover active:border-primary-text focus:border-primary-text`}
23
+ value={searchTerm}
24
+ onChange={(e) => onSearch(e.target.value as string)}
25
+ type="text"
26
+ name="location-search-bar-input"
27
+ />
28
+ </form>
29
+ );
30
+ });
@@ -29,7 +29,7 @@ export const SwipeListContainer = JSX<SwipeListContainerProps>(
29
29
  className = '',
30
30
  containerRef,
31
31
  activeIndex,
32
- visibleItemCount,
32
+ visibleItemCount = 0,
33
33
  gap = 0,
34
34
  padding = 0,
35
35
  snapAlign = 'snap-center',
@@ -54,11 +54,15 @@ export const SwipeListContainer = JSX<SwipeListContainerProps>(
54
54
  },
55
55
  [onVisibleItemsChange, onVisibleIndicesChange],
56
56
  );
57
+ const additionPadding = visibleItemCount > 0 ? gap * Number(visibleItemCount) - 1 : 0;
57
58
 
58
59
  return (
59
60
  <div
60
61
  className={`box-border overflow-auto flex horizontal-list no-scrollbar ${className}`}
61
- style={{ ...getContainerStyle(padding), gap: `${gap}px` }}
62
+ style={{
63
+ ...getContainerStyle(padding, additionPadding),
64
+ gap: `${gap}px`,
65
+ }}
62
66
  role="list"
63
67
  ref={containerRef}
64
68
  >
@@ -83,11 +87,11 @@ export const SwipeListContainer = JSX<SwipeListContainerProps>(
83
87
  );
84
88
 
85
89
  // Styles used to compensate outer container padding to get rid of clipping effect
86
- const getContainerStyle = (padding: number): Record<string, string> => ({
90
+ const getContainerStyle = (padding: number, additionalPadding = 0): Record<string, string> => ({
87
91
  marginLeft: `${-padding}px`,
88
92
  marginRight: `${-padding}px`,
89
93
  paddingLeft: `${padding}px`,
90
- paddingRight: `${padding}px`,
94
+ paddingRight: `${padding + additionalPadding}px`,
91
95
  });
92
96
 
93
97
  const getVisibleIndices = (itemsVisibilityList: ItemsVisibilityList) =>
@@ -0,0 +1,10 @@
1
+ export const groupBy = <K, V>(list: Array<V>, keyGetter: (input: V) => K): Map<K, Array<V>> => {
2
+ const map = new Map<K, Array<V>>();
3
+ list.forEach((item) => {
4
+ const key = keyGetter(item);
5
+ const collection = map.get(key);
6
+ map.set(key, [...(collection || []), item]);
7
+ });
8
+
9
+ return map;
10
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redneckz/wildless-cms-uni-blocks",
3
- "version": "0.6.41",
3
+ "version": "0.6.42",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "author": "ЦК",
@@ -185,7 +185,7 @@
185
185
  "path": "lib/common.css"
186
186
  },
187
187
  {
188
- "limit": "43 kB",
188
+ "limit": "45 kB",
189
189
  "path": "bundle/bundle.umd.min.js"
190
190
  }
191
191
  ],
@@ -43,6 +43,7 @@ import { ProductBlock } from './ProductBlock/ProductBlock';
43
43
  import { ProductGallery } from './ProductGallery/ProductGallery';
44
44
  import { ProductTile } from './ProductTile/ProductTile';
45
45
  import { PromoTile } from './PromoTile/PromoTile';
46
+ import { CarouselRecommendationCard } from './CarouselRecommendationCard/CarouselRecommendationCard';
46
47
  import { Recommendation } from './Recommendation/Recommendation';
47
48
  import { RollupItem } from './RollupItem/RollupItem';
48
49
  import { SafeDepositRental } from './SafeDepositRental/SafeDepositRental';
@@ -95,11 +96,10 @@ export const Blocks: BlocksRegistry = {
95
96
  ProductGallery,
96
97
  ProductTile,
97
98
  PromoTile,
98
- OfficeMap,
99
99
  OfficeServicesBlock,
100
100
  OtherProducts,
101
101
  OtherProductsItem,
102
- Recommendation,
102
+ CarouselRecommendationCard,
103
103
  RollupItem,
104
104
  SafeDepositRental,
105
105
  StepsBlock,
@@ -109,4 +109,6 @@ export const Blocks: BlocksRegistry = {
109
109
  Tile,
110
110
  VerticalLayout,
111
111
  Video,
112
+ Recommendation,
113
+ OfficeMap,
112
114
  };
@@ -1,13 +1,14 @@
1
- import type { BlockRendererOptions } from '../../BlockRenderer/BlockRendererOptions';
2
1
  import '../../setup-fixture';
3
2
  import { Blocks } from '../Blocks';
3
+ import { BUSINESS_CARD } from '../CarouselProgramsCard/CarouselProgramsCard.fixture';
4
4
  import { CARD, CARD_MINI, CARD_NEW } from '../CarouselCard/CarouselCard.fixture';
5
+ import { Carousel } from './Carousel';
6
+ import { CAROUSEL_RECOMMENDATION_CARD } from '../CarouselRecommendationCard/CarouselRecommendationCard.fixture';
5
7
  import { CATALOG_CARD } from '../CarouselCatalogCard/CarouselCatalogCard.fixture';
6
8
  import { INVESTMENT_CARD_WITH_SINGLE_COLUMN } from '../CarouselInvestmentCard/CarouselInvestmentCard.fixture';
7
9
  import { PRODUCT_CARD } from '../CarouselProductCard/CarouselProductCard.fixture';
8
- import { BUSINESS_CARD } from '../CarouselProgramsCard/CarouselProgramsCard.fixture';
9
10
  import { TARIFFS_CARD, TARIFFS_CARD_HIT } from '../CarouselTariffsCard/CarouselTariffsCard.fixture';
10
- import { Carousel } from './Carousel';
11
+ import type { BlockRendererOptions } from '../../BlockRenderer/BlockRendererOptions';
11
12
 
12
13
  const options = {
13
14
  blocksRegistry: Blocks,
@@ -127,7 +128,6 @@ export default {
127
128
  />
128
129
  </div>
129
130
  ),
130
-
131
131
  program: (
132
132
  <div className="container grid grid-cols-12">
133
133
  <Carousel
@@ -165,4 +165,22 @@ export default {
165
165
  />
166
166
  </div>
167
167
  ),
168
+ recommendations: (
169
+ <div className="container grid grid-cols-12">
170
+ <Carousel
171
+ className="col-span-12"
172
+ isBlur={true}
173
+ isCyclic={false}
174
+ block={{
175
+ type: 'Carousel',
176
+ blocks: new Array(6).fill({
177
+ type: 'CarouselRecommendationCard',
178
+ content: CAROUSEL_RECOMMENDATION_CARD,
179
+ style: ['col-span-4'],
180
+ }),
181
+ }}
182
+ options={options}
183
+ />
184
+ </div>
185
+ ),
168
186
  };
@@ -0,0 +1,19 @@
1
+ {
2
+ "content": {
3
+ "image": {
4
+ "format": "webp",
5
+ "size": {
6
+ "width": 180,
7
+ "height": 180
8
+ }
9
+ },
10
+ "title": "Заголовок 1",
11
+ "description": "Описание 1",
12
+ "socialMedia": [
13
+ { "href": "https://t.me" },
14
+ { "href": "https://vk.com" },
15
+ { "href": "https://ok.ru" }
16
+ ],
17
+ "version": "primary"
18
+ }
19
+ }
@@ -0,0 +1,47 @@
1
+ import type { LinkProps } from '../../model/LinkProps';
2
+ import type { Picture } from '../../model/Picture';
3
+ import '../../setup-fixture';
4
+ import { CarouselRecommendationCard } from './CarouselRecommendationCard';
5
+ import type { CarouselRecommendationCardContent } from './CarouselRecommendationCardContent';
6
+
7
+ const image: Picture = {
8
+ src: 'product-basket.png',
9
+ format: 'webp',
10
+ size: {
11
+ width: 290,
12
+ height: 290,
13
+ },
14
+ title: 'product-basket',
15
+ };
16
+
17
+ const socialMedia: LinkProps[] = [
18
+ { href: 'https://t.me' },
19
+ { href: 'https://vk.com' },
20
+ { href: 'https://ok.ru' },
21
+ ];
22
+
23
+ const items = ['Свежие новости', 'Акции и предложения', 'Ставки и котировки'];
24
+
25
+ export const CAROUSEL_RECOMMENDATION_CARD: CarouselRecommendationCardContent = {
26
+ title: 'РоссельхозБанк',
27
+ items,
28
+ image,
29
+ socialMedia,
30
+ };
31
+
32
+ export default {
33
+ default: (
34
+ <div className="container grid grid-cols-12 mb-1">
35
+ <CarouselRecommendationCard className="col-span-4" {...CAROUSEL_RECOMMENDATION_CARD} />
36
+ </div>
37
+ ),
38
+ secondary: (
39
+ <div className="container grid grid-cols-12 mb-1">
40
+ <CarouselRecommendationCard
41
+ className="col-span-4"
42
+ version="secondary"
43
+ {...CAROUSEL_RECOMMENDATION_CARD}
44
+ />
45
+ </div>
46
+ ),
47
+ };
@@ -0,0 +1,62 @@
1
+ import { BaseTile } from '../BaseTile/BaseTile';
2
+ import { BlockWrapper } from '../../ui-kit/BlockWrapper';
3
+ import { BorderVersionStyleMap } from '../../model/BorderVersion';
4
+ import { Heading } from '../../ui-kit/Heading/Heading';
5
+ import { Img } from '../../ui-kit/Img/Img';
6
+ import { JSX } from '@redneckz/uni-jsx';
7
+ import { List } from '../../ui-kit/List/List';
8
+ import { renderButton } from '../../ui-kit/Button/ButtonSection';
9
+ import { SocialMedia } from '../Footer/SocialMedia';
10
+ import { VersionStyleMap } from '../../model/BlockVersion';
11
+ import type { CarouselRecommendationCardContent } from './CarouselRecommendationCardContent';
12
+ import type { UniBlockProps } from '../../model/JSXBlock';
13
+
14
+ export interface RecommendationCardProps extends CarouselRecommendationCardContent, UniBlockProps {}
15
+
16
+ export const CarouselRecommendationCard = JSX<RecommendationCardProps>(
17
+ ({
18
+ button,
19
+ className = '',
20
+ description,
21
+ image,
22
+ items = [],
23
+ socialMedia = [],
24
+ title,
25
+ version = 'primary',
26
+ ...rest
27
+ }) => {
28
+ const tileTitle = title ? (
29
+ <Heading headingType="h5" as="h3" className="mb-3.5 z-10" title={title} />
30
+ ) : null;
31
+ const tileImage = image?.src ? (
32
+ <Img className="absolute bottom-0 right-0 m-0" image={image} />
33
+ ) : null;
34
+
35
+ return (
36
+ <BlockWrapper
37
+ className={`relative text-left border border-solid box-border p-7 min-w-[524px]
38
+ ${BorderVersionStyleMap[version]}
39
+ ${VersionStyleMap[version]}
40
+ ${className}`}
41
+ {...rest}
42
+ >
43
+ <BaseTile className="flex justify-between" title={tileTitle} image={tileImage}>
44
+ <div className="h-full flex flex-col justify-between">
45
+ {description ? <span className="mb-2">{description}</span> : null}
46
+ {items.length ? (
47
+ <List
48
+ className="text-xl-light flex flex-col flex-1 gap-2 max-w-[236px]"
49
+ items={items}
50
+ version={version}
51
+ />
52
+ ) : null}
53
+ {socialMedia.length ? (
54
+ <SocialMedia className="pt-10 pb-0" media={socialMedia} version={version} />
55
+ ) : null}
56
+ {button?.text ? <div className="pt-2 mt-16">{renderButton({ button })}</div> : null}
57
+ </div>
58
+ </BaseTile>
59
+ </BlockWrapper>
60
+ );
61
+ },
62
+ );
@@ -0,0 +1,9 @@
1
+ {
2
+ "content": {
3
+ "items": {
4
+ "image": {
5
+ "ui:field": "picture"
6
+ }
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,45 @@
1
+ import type { BlockVersion } from '../../model/BlockVersion';
2
+ import type { HeadlineCommonProps } from '../../model/HeadlineType';
3
+ import type { LinkCommonProps } from '../../model/LinkProps';
4
+ import type { Picture } from '../../model/Picture';
5
+ import type { ButtonProps } from '../../ui-kit/Button/ButtonProps';
6
+ import type { ListContent } from '../../ui-kit/List/ListContent';
7
+
8
+ /**
9
+ * @title Карточка рекомендаций
10
+ */
11
+ export interface CarouselRecommendationCardContent extends HeadlineCommonProps, ListContent {
12
+ /**
13
+ * @title Соц сети
14
+ * @minItems 3
15
+ * @default [
16
+ * { "href": "https://t.me" },
17
+ * { "href": "https://vk.com" },
18
+ * { "href": "https://ok.ru" },
19
+ * ]
20
+ */
21
+ socialMedia?: LinkCommonProps[];
22
+ /**
23
+ * @default {
24
+ * "format": "webp",
25
+ * "size": {
26
+ * "width": 290
27
+ * },
28
+ * "sources": [{
29
+ * "media": 1279,
30
+ * "width": 174,
31
+ * "format": "webp",
32
+ * "alignment": "southeast"
33
+ * }]
34
+ * }
35
+ */
36
+ image?: Picture;
37
+ /**
38
+ * @default {
39
+ * "text": "",
40
+ * "version": "secondary"
41
+ * }
42
+ */
43
+ button?: ButtonProps;
44
+ version?: BlockVersion;
45
+ }
@@ -25,10 +25,11 @@ export const Header = JSX<HeaderProps>(
25
25
  ({ bgColor = 'bg-white', className = '', showSubMenu = true, ...rest }) => {
26
26
  const router = useRouter();
27
27
 
28
- const { topItems, logo, defaultLocation, officesLink } = useSWRResource<SitemapDataProps>(
29
- projectSettings.SITEMAP || 'sitemap',
30
- rest.options?.page?.fallback,
31
- );
28
+ const { topItems, logo, defaultLocation, foreignOffices, officesLink } =
29
+ useSWRResource<SitemapDataProps>(
30
+ projectSettings.SITEMAP || 'sitemap',
31
+ rest.options?.page?.fallback,
32
+ );
32
33
 
33
34
  const activeTopItem = showSubMenu ? getActiveItem(topItems, router) : null;
34
35
 
@@ -56,6 +57,7 @@ export const Header = JSX<HeaderProps>(
56
57
  {topMenu}
57
58
  <HeaderSecondaryMenu
58
59
  className="ml-auto"
60
+ foreignOffices={foreignOffices}
59
61
  defaultLocation={defaultLocation}
60
62
  officesLink={officesLink}
61
63
  bgColor={bgColor}
@@ -1,8 +1,9 @@
1
1
  import { JSX } from '@redneckz/uni-jsx';
2
- import { useGeolocation } from '../../hooks/useGeolocation';
2
+ import { useLocation } from '../../hooks/useLocation';
3
3
  import type { VNode } from '../../model/VNode';
4
4
  import { Img } from '../../ui-kit/Img/Img';
5
5
  import { SearchBar } from '../../ui-kit/SearchBar/SearchBar';
6
+ import { Text } from '../../ui-kit/Text/Text';
6
7
  import type { DispositionItem } from './HeaderContent';
7
8
 
8
9
  export interface HeaderBurgerProps {
@@ -14,7 +15,7 @@ export interface HeaderBurgerProps {
14
15
 
15
16
  export const HeaderBurger = JSX<HeaderBurgerProps>(
16
17
  ({ burgerSubMenu, onClick, defaultLocation = '', children }) => {
17
- const [city, getCity] = useGeolocation(defaultLocation);
18
+ const [location] = useLocation(defaultLocation);
18
19
 
19
20
  return (
20
21
  <div className="absolute top-0 left-0 w-full h-full bg-white p-4 box-border z-20">
@@ -24,10 +25,7 @@ export const HeaderBurger = JSX<HeaderBurgerProps>(
24
25
  >
25
26
  <Img image="CloseIcon" width="24" height="24" asSVG />
26
27
  </button>
27
- <button
28
- onClick={getCity}
29
- className="flex items-center text-s text-secondary-text p-0 mb-4 bg-transparent cursor-pointer"
30
- >
28
+ <button className="flex items-center text-s p-0 mb-4 bg-transparent cursor-pointer">
31
29
  <Img
32
30
  image="GeolocationIcon"
33
31
  width="20"
@@ -35,7 +33,7 @@ export const HeaderBurger = JSX<HeaderBurgerProps>(
35
33
  className="text-primary-main box-border mr-2"
36
34
  asSVG
37
35
  />
38
- {city}
36
+ <Text color="text-secondary-text">{location.name}</Text>
39
37
  </button>
40
38
  {children}
41
39
  <div className="mb-7">{burgerSubMenu?.map(renderBurgerSubMenuItem)}</div>