@cloud-ru/uikit-product-header 5.0.17

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 (240) hide show
  1. package/CHANGELOG.md +3498 -0
  2. package/LICENSE +201 -0
  3. package/README.md +322 -0
  4. package/dist/cjs/components/HeaderLayout/HeaderLayout.d.ts +12 -0
  5. package/dist/cjs/components/HeaderLayout/HeaderLayout.js +25 -0
  6. package/dist/cjs/components/HeaderLayout/index.d.ts +1 -0
  7. package/dist/cjs/components/HeaderLayout/index.js +17 -0
  8. package/dist/cjs/components/HeaderLayout/styles.module.css +35 -0
  9. package/dist/cjs/components/Logo/Logo.d.ts +20 -0
  10. package/dist/cjs/components/Logo/Logo.js +61 -0
  11. package/dist/cjs/components/Logo/index.d.ts +1 -0
  12. package/dist/cjs/components/Logo/index.js +17 -0
  13. package/dist/cjs/components/Logo/styles.module.css +28 -0
  14. package/dist/cjs/components/MainMenu/Content/Content.d.ts +20 -0
  15. package/dist/cjs/components/MainMenu/Content/Content.js +36 -0
  16. package/dist/cjs/components/MainMenu/Content/index.d.ts +1 -0
  17. package/dist/cjs/components/MainMenu/Content/index.js +17 -0
  18. package/dist/cjs/components/MainMenu/Content/styles.module.css +40 -0
  19. package/dist/cjs/components/MainMenu/MainMenu.d.ts +4 -0
  20. package/dist/cjs/components/MainMenu/MainMenu.js +16 -0
  21. package/dist/cjs/components/MainMenu/MenuDesktop/MenuDesktop.d.ts +2 -0
  22. package/dist/cjs/components/MainMenu/MenuDesktop/MenuDesktop.js +34 -0
  23. package/dist/cjs/components/MainMenu/MenuDesktop/index.d.ts +1 -0
  24. package/dist/cjs/components/MainMenu/MenuDesktop/index.js +17 -0
  25. package/dist/cjs/components/MainMenu/MenuDesktop/styles.module.css +94 -0
  26. package/dist/cjs/components/MainMenu/MenuMobile/MenuMobile.d.ts +2 -0
  27. package/dist/cjs/components/MainMenu/MenuMobile/MenuMobile.js +31 -0
  28. package/dist/cjs/components/MainMenu/MenuMobile/index.d.ts +1 -0
  29. package/dist/cjs/components/MainMenu/MenuMobile/index.js +17 -0
  30. package/dist/cjs/components/MainMenu/MenuMobile/styles.module.css +23 -0
  31. package/dist/cjs/components/MainMenu/Search/SearchDesktop/SearchDesktop.d.ts +2 -0
  32. package/dist/cjs/components/MainMenu/Search/SearchDesktop/SearchDesktop.js +18 -0
  33. package/dist/cjs/components/MainMenu/Search/SearchDesktop/index.d.ts +1 -0
  34. package/dist/cjs/components/MainMenu/Search/SearchDesktop/index.js +17 -0
  35. package/dist/cjs/components/MainMenu/Search/SearchDesktop/styles.module.css +17 -0
  36. package/dist/cjs/components/MainMenu/Search/SearchMobile/SearchMobile.d.ts +2 -0
  37. package/dist/cjs/components/MainMenu/Search/SearchMobile/SearchMobile.js +42 -0
  38. package/dist/cjs/components/MainMenu/Search/SearchMobile/constants.d.ts +4 -0
  39. package/dist/cjs/components/MainMenu/Search/SearchMobile/constants.js +7 -0
  40. package/dist/cjs/components/MainMenu/Search/SearchMobile/hooks.d.ts +12 -0
  41. package/dist/cjs/components/MainMenu/Search/SearchMobile/hooks.js +40 -0
  42. package/dist/cjs/components/MainMenu/Search/SearchMobile/index.d.ts +1 -0
  43. package/dist/cjs/components/MainMenu/Search/SearchMobile/index.js +17 -0
  44. package/dist/cjs/components/MainMenu/Search/SearchMobile/styles.module.css +57 -0
  45. package/dist/cjs/components/MainMenu/Search/SearchSettingsButton/SearchSettingsButton.d.ts +4 -0
  46. package/dist/cjs/components/MainMenu/Search/SearchSettingsButton/SearchSettingsButton.js +13 -0
  47. package/dist/cjs/components/MainMenu/Search/SearchSettingsButton/index.d.ts +1 -0
  48. package/dist/cjs/components/MainMenu/Search/SearchSettingsButton/index.js +17 -0
  49. package/dist/cjs/components/MainMenu/Search/SearchSettingsButton/styles.module.css +11 -0
  50. package/dist/cjs/components/MainMenu/Search/index.d.ts +3 -0
  51. package/dist/cjs/components/MainMenu/Search/index.js +19 -0
  52. package/dist/cjs/components/MainMenu/Search/types.d.ts +14 -0
  53. package/dist/cjs/components/MainMenu/Search/types.js +2 -0
  54. package/dist/cjs/components/MainMenu/Search/useSearch.d.ts +8 -0
  55. package/dist/cjs/components/MainMenu/Search/useSearch.js +169 -0
  56. package/dist/cjs/components/MainMenu/hooks.d.ts +10 -0
  57. package/dist/cjs/components/MainMenu/hooks.js +108 -0
  58. package/dist/cjs/components/MainMenu/index.d.ts +4 -0
  59. package/dist/cjs/components/MainMenu/index.js +20 -0
  60. package/dist/cjs/components/MainMenu/styles.module.css +28 -0
  61. package/dist/cjs/components/MainMenu/types.d.ts +49 -0
  62. package/dist/cjs/components/MainMenu/types.js +2 -0
  63. package/dist/cjs/components/PathBreadcrumbs/PathBreadcrumbs.d.ts +7 -0
  64. package/dist/cjs/components/PathBreadcrumbs/PathBreadcrumbs.js +12 -0
  65. package/dist/cjs/components/PathBreadcrumbs/index.d.ts +1 -0
  66. package/dist/cjs/components/PathBreadcrumbs/index.js +17 -0
  67. package/dist/cjs/components/PathBreadcrumbs/styles.module.css +5 -0
  68. package/dist/cjs/components/PlatformLogo/Container.d.ts +12 -0
  69. package/dist/cjs/components/PlatformLogo/Container.js +28 -0
  70. package/dist/cjs/components/PlatformLogo/index.d.ts +4 -0
  71. package/dist/cjs/components/PlatformLogo/index.js +9 -0
  72. package/dist/cjs/components/PlatformLogo/styles.module.css +11 -0
  73. package/dist/cjs/components/UserMenu/UserMenu.d.ts +14 -0
  74. package/dist/cjs/components/UserMenu/UserMenu.js +54 -0
  75. package/dist/cjs/components/UserMenu/hooks/useLogoutItem.d.ts +6 -0
  76. package/dist/cjs/components/UserMenu/hooks/useLogoutItem.js +21 -0
  77. package/dist/cjs/components/UserMenu/hooks/useProfileItem.d.ts +3 -0
  78. package/dist/cjs/components/UserMenu/hooks/useProfileItem.js +29 -0
  79. package/dist/cjs/components/UserMenu/hooks/useThemeItem.d.ts +6 -0
  80. package/dist/cjs/components/UserMenu/hooks/useThemeItem.js +75 -0
  81. package/dist/cjs/components/UserMenu/hooks/useUserMenuItems.d.ts +13 -0
  82. package/dist/cjs/components/UserMenu/hooks/useUserMenuItems.js +42 -0
  83. package/dist/cjs/components/UserMenu/index.d.ts +2 -0
  84. package/dist/cjs/components/UserMenu/index.js +18 -0
  85. package/dist/cjs/components/UserMenu/styles.module.css +21 -0
  86. package/dist/cjs/components/UserMenu/types.d.ts +20 -0
  87. package/dist/cjs/components/UserMenu/types.js +8 -0
  88. package/dist/cjs/components/index.d.ts +6 -0
  89. package/dist/cjs/components/index.js +22 -0
  90. package/dist/cjs/hooks/index.d.ts +1 -0
  91. package/dist/cjs/hooks/index.js +17 -0
  92. package/dist/cjs/hooks/useLocalStorage.d.ts +1 -0
  93. package/dist/cjs/hooks/useLocalStorage.js +13 -0
  94. package/dist/cjs/index.d.ts +2 -0
  95. package/dist/cjs/index.js +18 -0
  96. package/dist/esm/components/HeaderLayout/HeaderLayout.d.ts +12 -0
  97. package/dist/esm/components/HeaderLayout/HeaderLayout.js +19 -0
  98. package/dist/esm/components/HeaderLayout/index.d.ts +1 -0
  99. package/dist/esm/components/HeaderLayout/index.js +1 -0
  100. package/dist/esm/components/HeaderLayout/styles.module.css +35 -0
  101. package/dist/esm/components/Logo/Logo.d.ts +20 -0
  102. package/dist/esm/components/Logo/Logo.js +54 -0
  103. package/dist/esm/components/Logo/index.d.ts +1 -0
  104. package/dist/esm/components/Logo/index.js +1 -0
  105. package/dist/esm/components/Logo/styles.module.css +28 -0
  106. package/dist/esm/components/MainMenu/Content/Content.d.ts +20 -0
  107. package/dist/esm/components/MainMenu/Content/Content.js +30 -0
  108. package/dist/esm/components/MainMenu/Content/index.d.ts +1 -0
  109. package/dist/esm/components/MainMenu/Content/index.js +1 -0
  110. package/dist/esm/components/MainMenu/Content/styles.module.css +40 -0
  111. package/dist/esm/components/MainMenu/MainMenu.d.ts +4 -0
  112. package/dist/esm/components/MainMenu/MainMenu.js +13 -0
  113. package/dist/esm/components/MainMenu/MenuDesktop/MenuDesktop.d.ts +2 -0
  114. package/dist/esm/components/MainMenu/MenuDesktop/MenuDesktop.js +28 -0
  115. package/dist/esm/components/MainMenu/MenuDesktop/index.d.ts +1 -0
  116. package/dist/esm/components/MainMenu/MenuDesktop/index.js +1 -0
  117. package/dist/esm/components/MainMenu/MenuDesktop/styles.module.css +94 -0
  118. package/dist/esm/components/MainMenu/MenuMobile/MenuMobile.d.ts +2 -0
  119. package/dist/esm/components/MainMenu/MenuMobile/MenuMobile.js +25 -0
  120. package/dist/esm/components/MainMenu/MenuMobile/index.d.ts +1 -0
  121. package/dist/esm/components/MainMenu/MenuMobile/index.js +1 -0
  122. package/dist/esm/components/MainMenu/MenuMobile/styles.module.css +23 -0
  123. package/dist/esm/components/MainMenu/Search/SearchDesktop/SearchDesktop.d.ts +2 -0
  124. package/dist/esm/components/MainMenu/Search/SearchDesktop/SearchDesktop.js +12 -0
  125. package/dist/esm/components/MainMenu/Search/SearchDesktop/index.d.ts +1 -0
  126. package/dist/esm/components/MainMenu/Search/SearchDesktop/index.js +1 -0
  127. package/dist/esm/components/MainMenu/Search/SearchDesktop/styles.module.css +17 -0
  128. package/dist/esm/components/MainMenu/Search/SearchMobile/SearchMobile.d.ts +2 -0
  129. package/dist/esm/components/MainMenu/Search/SearchMobile/SearchMobile.js +36 -0
  130. package/dist/esm/components/MainMenu/Search/SearchMobile/constants.d.ts +4 -0
  131. package/dist/esm/components/MainMenu/Search/SearchMobile/constants.js +4 -0
  132. package/dist/esm/components/MainMenu/Search/SearchMobile/hooks.d.ts +12 -0
  133. package/dist/esm/components/MainMenu/Search/SearchMobile/hooks.js +34 -0
  134. package/dist/esm/components/MainMenu/Search/SearchMobile/index.d.ts +1 -0
  135. package/dist/esm/components/MainMenu/Search/SearchMobile/index.js +1 -0
  136. package/dist/esm/components/MainMenu/Search/SearchMobile/styles.module.css +57 -0
  137. package/dist/esm/components/MainMenu/Search/SearchSettingsButton/SearchSettingsButton.d.ts +4 -0
  138. package/dist/esm/components/MainMenu/Search/SearchSettingsButton/SearchSettingsButton.js +7 -0
  139. package/dist/esm/components/MainMenu/Search/SearchSettingsButton/index.d.ts +1 -0
  140. package/dist/esm/components/MainMenu/Search/SearchSettingsButton/index.js +1 -0
  141. package/dist/esm/components/MainMenu/Search/SearchSettingsButton/styles.module.css +11 -0
  142. package/dist/esm/components/MainMenu/Search/index.d.ts +3 -0
  143. package/dist/esm/components/MainMenu/Search/index.js +3 -0
  144. package/dist/esm/components/MainMenu/Search/types.d.ts +14 -0
  145. package/dist/esm/components/MainMenu/Search/types.js +1 -0
  146. package/dist/esm/components/MainMenu/Search/useSearch.d.ts +8 -0
  147. package/dist/esm/components/MainMenu/Search/useSearch.js +161 -0
  148. package/dist/esm/components/MainMenu/hooks.d.ts +10 -0
  149. package/dist/esm/components/MainMenu/hooks.js +101 -0
  150. package/dist/esm/components/MainMenu/index.d.ts +4 -0
  151. package/dist/esm/components/MainMenu/index.js +4 -0
  152. package/dist/esm/components/MainMenu/styles.module.css +28 -0
  153. package/dist/esm/components/MainMenu/types.d.ts +49 -0
  154. package/dist/esm/components/MainMenu/types.js +1 -0
  155. package/dist/esm/components/PathBreadcrumbs/PathBreadcrumbs.d.ts +7 -0
  156. package/dist/esm/components/PathBreadcrumbs/PathBreadcrumbs.js +6 -0
  157. package/dist/esm/components/PathBreadcrumbs/index.d.ts +1 -0
  158. package/dist/esm/components/PathBreadcrumbs/index.js +1 -0
  159. package/dist/esm/components/PathBreadcrumbs/styles.module.css +5 -0
  160. package/dist/esm/components/PlatformLogo/Container.d.ts +12 -0
  161. package/dist/esm/components/PlatformLogo/Container.js +20 -0
  162. package/dist/esm/components/PlatformLogo/index.d.ts +4 -0
  163. package/dist/esm/components/PlatformLogo/index.js +6 -0
  164. package/dist/esm/components/PlatformLogo/styles.module.css +11 -0
  165. package/dist/esm/components/UserMenu/UserMenu.d.ts +14 -0
  166. package/dist/esm/components/UserMenu/UserMenu.js +48 -0
  167. package/dist/esm/components/UserMenu/hooks/useLogoutItem.d.ts +6 -0
  168. package/dist/esm/components/UserMenu/hooks/useLogoutItem.js +18 -0
  169. package/dist/esm/components/UserMenu/hooks/useProfileItem.d.ts +3 -0
  170. package/dist/esm/components/UserMenu/hooks/useProfileItem.js +23 -0
  171. package/dist/esm/components/UserMenu/hooks/useThemeItem.d.ts +6 -0
  172. package/dist/esm/components/UserMenu/hooks/useThemeItem.js +72 -0
  173. package/dist/esm/components/UserMenu/hooks/useUserMenuItems.d.ts +13 -0
  174. package/dist/esm/components/UserMenu/hooks/useUserMenuItems.js +39 -0
  175. package/dist/esm/components/UserMenu/index.d.ts +2 -0
  176. package/dist/esm/components/UserMenu/index.js +2 -0
  177. package/dist/esm/components/UserMenu/styles.module.css +21 -0
  178. package/dist/esm/components/UserMenu/types.d.ts +20 -0
  179. package/dist/esm/components/UserMenu/types.js +5 -0
  180. package/dist/esm/components/index.d.ts +6 -0
  181. package/dist/esm/components/index.js +6 -0
  182. package/dist/esm/hooks/index.d.ts +1 -0
  183. package/dist/esm/hooks/index.js +1 -0
  184. package/dist/esm/hooks/useLocalStorage.d.ts +1 -0
  185. package/dist/esm/hooks/useLocalStorage.js +10 -0
  186. package/dist/esm/index.d.ts +2 -0
  187. package/dist/esm/index.js +2 -0
  188. package/package.json +68 -0
  189. package/src/components/HeaderLayout/HeaderLayout.tsx +46 -0
  190. package/src/components/HeaderLayout/index.ts +1 -0
  191. package/src/components/HeaderLayout/styles.module.scss +38 -0
  192. package/src/components/Logo/Logo.tsx +93 -0
  193. package/src/components/Logo/index.ts +1 -0
  194. package/src/components/Logo/styles.module.scss +30 -0
  195. package/src/components/MainMenu/Content/Content.tsx +137 -0
  196. package/src/components/MainMenu/Content/index.ts +1 -0
  197. package/src/components/MainMenu/Content/styles.module.scss +35 -0
  198. package/src/components/MainMenu/MainMenu.tsx +51 -0
  199. package/src/components/MainMenu/MenuDesktop/MenuDesktop.tsx +120 -0
  200. package/src/components/MainMenu/MenuDesktop/index.ts +1 -0
  201. package/src/components/MainMenu/MenuDesktop/styles.module.scss +108 -0
  202. package/src/components/MainMenu/MenuMobile/MenuMobile.tsx +83 -0
  203. package/src/components/MainMenu/MenuMobile/index.ts +1 -0
  204. package/src/components/MainMenu/MenuMobile/styles.module.scss +26 -0
  205. package/src/components/MainMenu/Search/SearchDesktop/SearchDesktop.tsx +46 -0
  206. package/src/components/MainMenu/Search/SearchDesktop/index.ts +1 -0
  207. package/src/components/MainMenu/Search/SearchDesktop/styles.module.scss +21 -0
  208. package/src/components/MainMenu/Search/SearchMobile/SearchMobile.tsx +102 -0
  209. package/src/components/MainMenu/Search/SearchMobile/constants.ts +4 -0
  210. package/src/components/MainMenu/Search/SearchMobile/hooks.ts +43 -0
  211. package/src/components/MainMenu/Search/SearchMobile/index.ts +1 -0
  212. package/src/components/MainMenu/Search/SearchMobile/styles.module.scss +72 -0
  213. package/src/components/MainMenu/Search/SearchSettingsButton/SearchSettingsButton.tsx +22 -0
  214. package/src/components/MainMenu/Search/SearchSettingsButton/index.ts +1 -0
  215. package/src/components/MainMenu/Search/SearchSettingsButton/styles.module.scss +13 -0
  216. package/src/components/MainMenu/Search/index.ts +3 -0
  217. package/src/components/MainMenu/Search/types.ts +20 -0
  218. package/src/components/MainMenu/Search/useSearch.tsx +212 -0
  219. package/src/components/MainMenu/hooks.tsx +135 -0
  220. package/src/components/MainMenu/index.ts +4 -0
  221. package/src/components/MainMenu/styles.module.scss +28 -0
  222. package/src/components/MainMenu/types.ts +62 -0
  223. package/src/components/PathBreadcrumbs/PathBreadcrumbs.tsx +21 -0
  224. package/src/components/PathBreadcrumbs/index.ts +1 -0
  225. package/src/components/PathBreadcrumbs/styles.module.scss +10 -0
  226. package/src/components/PlatformLogo/Container.tsx +32 -0
  227. package/src/components/PlatformLogo/index.ts +8 -0
  228. package/src/components/PlatformLogo/styles.module.scss +13 -0
  229. package/src/components/UserMenu/UserMenu.tsx +138 -0
  230. package/src/components/UserMenu/hooks/useLogoutItem.tsx +28 -0
  231. package/src/components/UserMenu/hooks/useProfileItem.tsx +41 -0
  232. package/src/components/UserMenu/hooks/useThemeItem.tsx +116 -0
  233. package/src/components/UserMenu/hooks/useUserMenuItems.ts +77 -0
  234. package/src/components/UserMenu/index.ts +2 -0
  235. package/src/components/UserMenu/styles.module.scss +21 -0
  236. package/src/components/UserMenu/types.ts +24 -0
  237. package/src/components/index.ts +6 -0
  238. package/src/hooks/index.ts +1 -0
  239. package/src/hooks/useLocalStorage.ts +15 -0
  240. package/src/index.ts +2 -0
@@ -0,0 +1,6 @@
1
+ import { DroplistProps } from '@snack-uikit/list';
2
+ import { ThemeProps } from '../types';
3
+ export declare function useThemeItem({ value: themeMode, onChange, isMobile, onClose, }: ThemeProps & {
4
+ isMobile?: boolean;
5
+ onClose?(): void;
6
+ }): DroplistProps['items'][0];
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCallback, useMemo, useState } from 'react';
3
+ import { ChevronRightSVG, DaySVG, LaptopPhoneSVG, NightSVG, ThemeContrastSVG } from '@sbercloud/uikit-product-icons';
4
+ import { useLocale } from '@sbercloud/uikit-product-locale';
5
+ import { MobileModalCustom } from '@sbercloud/uikit-product-mobile-modal';
6
+ import { List } from '@snack-uikit/list';
7
+ import { THEME_MODE } from '../types';
8
+ export function useThemeItem({ value: themeMode, onChange, isMobile, onClose, }) {
9
+ const { t } = useLocale('Header');
10
+ const [open, setOpen] = useState(false);
11
+ const handleClick = useCallback((themeMode) => () => {
12
+ onChange === null || onChange === void 0 ? void 0 : onChange(themeMode);
13
+ !isMobile && (onClose === null || onClose === void 0 ? void 0 : onClose());
14
+ }, [isMobile, onChange, onClose]);
15
+ const themeModeOptions = useMemo(() => [
16
+ {
17
+ beforeContent: _jsx(DaySVG, {}),
18
+ content: {
19
+ option: t('themeModeLight'),
20
+ },
21
+ onClick: handleClick(THEME_MODE.Light),
22
+ checked: themeMode === THEME_MODE.Light,
23
+ 'data-test-id': 'header__user-menu__theme-mode__light-option',
24
+ },
25
+ {
26
+ beforeContent: _jsx(NightSVG, {}),
27
+ content: {
28
+ option: t('themeModeDark'),
29
+ },
30
+ checked: themeMode === THEME_MODE.Dark,
31
+ onClick: handleClick(THEME_MODE.Dark),
32
+ 'data-test-id': 'header__user-menu__theme-mode__dark-option',
33
+ },
34
+ {
35
+ beforeContent: _jsx(LaptopPhoneSVG, {}),
36
+ content: {
37
+ option: t('themeModeSystem'),
38
+ },
39
+ checked: themeMode === THEME_MODE.System,
40
+ onClick: handleClick(THEME_MODE.System),
41
+ 'data-test-id': 'header__user-menu__theme-mode__system-option',
42
+ },
43
+ ], [handleClick, t, themeMode]);
44
+ const themeItem = useMemo(() => ({
45
+ type: 'next-list',
46
+ content: {
47
+ option: t('themeModeLabel'),
48
+ },
49
+ placement: 'left-start',
50
+ beforeContent: _jsx(ThemeContrastSVG, {}),
51
+ 'data-test-id': 'header__user-menu__theme-mode',
52
+ items: themeModeOptions,
53
+ }), [t, themeModeOptions]);
54
+ const mobileThemeItem = useMemo(() => ({
55
+ id: 'header__user-menu__theme-mode',
56
+ beforeContent: _jsx(ThemeContrastSVG, {}),
57
+ 'data-test-id': 'header__user-menu__theme-mode',
58
+ afterContent: (_jsx("span", { style: {
59
+ color: 'var(--sys-neutral-text-light)',
60
+ }, children: _jsx(ChevronRightSVG, {}) })),
61
+ content: {
62
+ option: t('themeModeLabel'),
63
+ },
64
+ onClick: () => {
65
+ setOpen(true);
66
+ },
67
+ itemWrapRender: (node) => (_jsxs(_Fragment, { children: [node, _jsxs(MobileModalCustom, { open: open, onClose: () => {
68
+ setOpen(false);
69
+ }, closeButtonEnabled: true, closeOnPopstate: true, children: [_jsx(MobileModalCustom.Header, { title: t('themeModeLabel') }), _jsx(List, { items: themeModeOptions, size: 'l', selection: { mode: 'single', value: themeMode } })] })] })),
70
+ }), [open, t, themeMode, themeModeOptions]);
71
+ return isMobile ? mobileThemeItem : themeItem;
72
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseItemProps, ListProps } from '@snack-uikit/list';
2
+ import { ThemeProps, UserProfileProps } from '../types';
3
+ type UseMenuItems = {
4
+ profile: UserProfileProps;
5
+ theme?: ThemeProps;
6
+ items?: ListProps['items'];
7
+ settingItems?: BaseItemProps[];
8
+ onLogout?(): void;
9
+ onClose?(): void;
10
+ isMobile?: boolean;
11
+ };
12
+ export declare function useUserMenuItems({ profile, theme, onLogout, items: itemsProp, isMobile, onClose, settingItems, }: UseMenuItems): import("@snack-uikit/list/dist/esm/components/Items").Item[];
13
+ export {};
@@ -0,0 +1,39 @@
1
+ import { useMemo } from 'react';
2
+ import { isBaseItemProps } from '@snack-uikit/list';
3
+ import { useLogoutItem } from './useLogoutItem';
4
+ import { useProfileItem } from './useProfileItem';
5
+ import { useThemeItem } from './useThemeItem';
6
+ const DIVIDER_ITEM = {
7
+ type: 'group',
8
+ divider: true,
9
+ items: [],
10
+ };
11
+ export function useUserMenuItems({ profile, theme, onLogout, items: itemsProp = [], isMobile, onClose, settingItems = [], }) {
12
+ const profileItem = useProfileItem(profile);
13
+ const themeItem = useThemeItem(Object.assign(Object.assign({}, (theme || {})), { isMobile, onClose }));
14
+ const logoutItem = useLogoutItem({ onLogout });
15
+ const items = useMemo(() => {
16
+ let items = [profileItem];
17
+ if (themeItem) {
18
+ items = items.concat([DIVIDER_ITEM, themeItem]);
19
+ }
20
+ items = items.concat(itemsProp);
21
+ items = items.concat(logoutItem);
22
+ if (isMobile && Boolean(settingItems === null || settingItems === void 0 ? void 0 : settingItems.length)) {
23
+ items = items.concat([DIVIDER_ITEM, ...settingItems]);
24
+ }
25
+ return items.map(item => {
26
+ if (isBaseItemProps(item) && item.id !== 'header__user-menu__theme-mode') {
27
+ return Object.assign(Object.assign({}, item), { onClick: (e) => {
28
+ var _a;
29
+ (_a = item.onClick) === null || _a === void 0 ? void 0 : _a.call(item, e);
30
+ if (!e.metaKey) {
31
+ onClose === null || onClose === void 0 ? void 0 : onClose();
32
+ }
33
+ } });
34
+ }
35
+ return item;
36
+ });
37
+ }, [isMobile, itemsProp, logoutItem, onClose, profileItem, settingItems, themeItem]);
38
+ return items;
39
+ }
@@ -0,0 +1,2 @@
1
+ export * from './UserMenu';
2
+ export * from './types';
@@ -0,0 +1,2 @@
1
+ export * from './UserMenu';
2
+ export * from './types';
@@ -0,0 +1,21 @@
1
+ .userMenuDroplist{
2
+ width:272px;
3
+ }
4
+
5
+ .mobileList{
6
+ padding:16px;
7
+ padding-top:0;
8
+ }
9
+
10
+ .settingIcon{
11
+ color:var(--sys-neutral-text-light, #8b8e9b);
12
+ }
13
+
14
+ .userMenuInfoItem [data-test-id=list__base-item-option]{
15
+ font-family:var(--sans-label-m-font-family, SB Sans Interface);
16
+ font-weight:var(--sans-label-m-font-weight, Semibold);
17
+ line-height:var(--sans-label-m-line-height, 16px);
18
+ font-size:var(--sans-label-m-font-size, 12px);
19
+ letter-spacing:var(--sans-label-m-letter-spacing, 0px);
20
+ paragraph-spacing:var(--sans-label-m-paragraph-spacing, 6.6px);
21
+ }
@@ -0,0 +1,20 @@
1
+ import { MouseEvent, ReactNode } from 'react';
2
+ export type UserProfileProps = {
3
+ fullName?: string;
4
+ email?: string;
5
+ inviteCount?: number;
6
+ onClick?(e: MouseEvent<HTMLElement>): void;
7
+ itemWrapRender?(node: ReactNode): ReactNode;
8
+ };
9
+ type ValueOf<T> = T[keyof T];
10
+ export declare const THEME_MODE: {
11
+ readonly Light: "light";
12
+ readonly Dark: "dark";
13
+ readonly System: "system";
14
+ };
15
+ export type ThemeMode = ValueOf<typeof THEME_MODE>;
16
+ export type ThemeProps = {
17
+ value?: ThemeMode;
18
+ onChange?(themeMode: ThemeMode): void;
19
+ };
20
+ export {};
@@ -0,0 +1,5 @@
1
+ export const THEME_MODE = {
2
+ Light: 'light',
3
+ Dark: 'dark',
4
+ System: 'system',
5
+ };
@@ -0,0 +1,6 @@
1
+ export * from './HeaderLayout';
2
+ export * from './MainMenu';
3
+ export * from './UserMenu';
4
+ export * from './Logo';
5
+ export * from './PathBreadcrumbs';
6
+ export * from './PlatformLogo';
@@ -0,0 +1,6 @@
1
+ export * from './HeaderLayout';
2
+ export * from './MainMenu';
3
+ export * from './UserMenu';
4
+ export * from './Logo';
5
+ export * from './PathBreadcrumbs';
6
+ export * from './PlatformLogo';
@@ -0,0 +1 @@
1
+ export * from './useLocalStorage';
@@ -0,0 +1 @@
1
+ export * from './useLocalStorage';
@@ -0,0 +1 @@
1
+ export declare function useLocalStorage<T extends string = string>(key: string, defaultValue: T): [T, (newValue: T) => void];
@@ -0,0 +1,10 @@
1
+ import { useCallback, useState } from 'react';
2
+ export function useLocalStorage(key, defaultValue) {
3
+ var _a;
4
+ const [value, setValueState] = useState((_a = localStorage.getItem(key)) !== null && _a !== void 0 ? _a : defaultValue);
5
+ const setValue = useCallback((newValue) => {
6
+ localStorage.setItem(key, newValue);
7
+ setValueState(newValue);
8
+ }, [key]);
9
+ return [value, setValue];
10
+ }
@@ -0,0 +1,2 @@
1
+ export * from './components';
2
+ export * from './hooks';
@@ -0,0 +1,2 @@
1
+ export * from './components';
2
+ export * from './hooks';
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@cloud-ru/uikit-product-header",
3
+ "title": "Header",
4
+ "version": "5.0.17",
5
+ "sideEffects": [
6
+ "*.css",
7
+ "*.woff",
8
+ "*.woff2"
9
+ ],
10
+ "description": "Common header",
11
+ "types": "./dist/esm/index.d.ts",
12
+ "exports": {
13
+ "import": "./dist/esm/index.js",
14
+ "require": "./dist/cjs/index.js"
15
+ },
16
+ "files": [
17
+ "dist/esm",
18
+ "dist/cjs",
19
+ "src",
20
+ "./CHANGELOG.md",
21
+ "./LICENSE"
22
+ ],
23
+ "homepage": "https://gitverse.ru/cloud-ru-tech/uikit-product/-/tree/master/packages/header",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://gitverse.ru/cloud-ru-tech/uikit-product.git",
27
+ "directory": "packages/header"
28
+ },
29
+ "author": {
30
+ "name": "Akhremenko Grigorii",
31
+ "url": "https://github.com/AGrigorii"
32
+ },
33
+ "license": "Apache-2.0",
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "scripts": {},
38
+ "dependencies": {
39
+ "@cloud-ru/uikit-product-card-predefined": "0.8.12",
40
+ "@cloud-ru/uikit-product-icons": "15.1.1",
41
+ "@cloud-ru/uikit-product-mobile-drawer": "0.9.15",
42
+ "@cloud-ru/uikit-product-mobile-modal": "0.9.18",
43
+ "@cloud-ru/uikit-product-title-clickable": "0.0.48",
44
+ "@cloud-ru/uikit-product-utils": "7.0.0",
45
+ "@snack-uikit/avatar": "0.8.14",
46
+ "@snack-uikit/breadcrumbs": "0.11.22",
47
+ "@snack-uikit/button": "0.19.16",
48
+ "@snack-uikit/chips": "0.28.1",
49
+ "@snack-uikit/drawer": "0.13.4",
50
+ "@snack-uikit/list": "0.32.2",
51
+ "@snack-uikit/scroll": "0.10.5",
52
+ "@snack-uikit/search": "0.12.13",
53
+ "@snack-uikit/skeleton": "0.6.9",
54
+ "@snack-uikit/typography": "0.8.11",
55
+ "@snack-uikit/utils": "4.0.0",
56
+ "classnames": "2.5.1",
57
+ "fuse.js": "7.1.0",
58
+ "lodash.debounce": "4.0.8",
59
+ "react-transition-state": "2.1.3"
60
+ },
61
+ "devDependencies": {
62
+ "@types/lodash.debounce": "4.0.9"
63
+ },
64
+ "peerDependencies": {
65
+ "@cloud-ru/uikit-product-locale": "*"
66
+ },
67
+ "gitHead": "e8bd79bc92b26a8f52611972eec98a867536ccd3"
68
+ }
@@ -0,0 +1,46 @@
1
+ import cn from 'classnames';
2
+ import { ReactNode } from 'react';
3
+
4
+ import { extractSupportProps, WithSupportProps } from '@cloud-ru/uikit-product-utils';
5
+
6
+ import styles from './styles.module.scss';
7
+
8
+ export type HeaderLayoutProps = WithSupportProps<{
9
+ className?: string;
10
+ menu?: ReactNode;
11
+ logo?: ReactNode;
12
+ select?: ReactNode;
13
+ breadcrumbs?: ReactNode;
14
+ toolbar?: ReactNode;
15
+ isMobile?: boolean;
16
+ }>;
17
+
18
+ export function HeaderLayout({
19
+ menu,
20
+ logo,
21
+ select,
22
+ breadcrumbs,
23
+ toolbar,
24
+ className,
25
+ isMobile,
26
+ ...rest
27
+ }: HeaderLayoutProps) {
28
+ return (
29
+ <header className={cn(styles.header, className)} {...extractSupportProps(rest)}>
30
+ <div className={styles.top}>
31
+ <div className={styles.left}>
32
+ {menu}
33
+
34
+ {logo}
35
+
36
+ {!isMobile && select}
37
+ {!isMobile && breadcrumbs}
38
+ </div>
39
+
40
+ <div className={styles.right}>{toolbar}</div>
41
+ </div>
42
+
43
+ {isMobile && Boolean(breadcrumbs) && <div className={styles.bottom}>{breadcrumbs}</div>}
44
+ </header>
45
+ );
46
+ }
@@ -0,0 +1 @@
1
+ export * from './HeaderLayout';
@@ -0,0 +1,38 @@
1
+ @use '@sbercloud/figma-tokens-cloud-platform/build/scss/components/styles-tokens-element' as ste;
2
+
3
+ .header {
4
+ box-sizing: border-box;
5
+
6
+ background-color: ste.$sys-neutral-background;
7
+ }
8
+
9
+ .top {
10
+ display: flex;
11
+ box-sizing: border-box;
12
+ align-items: center;
13
+ padding: 0 ste.$dimension-1m 0 0;
14
+ height: ste.$dimension-6m;
15
+ gap: ste.$dimension-2m;
16
+ justify-content: space-between;
17
+ border-bottom: ste.$border-width-012m ste.$border-styles-solid ste.$sys-neutral-decor-default;
18
+ }
19
+
20
+ .bottom {
21
+ height: 32px;
22
+ box-sizing: border-box;
23
+ border-bottom: ste.$border-width-012m ste.$border-styles-solid ste.$sys-neutral-decor-default;
24
+ display: flex;
25
+ align-items: center;
26
+ overflow: hidden;
27
+ }
28
+
29
+ .left {
30
+ display: flex;
31
+ min-width: 0;
32
+ align-items: center;
33
+ }
34
+
35
+ .right {
36
+ display: flex;
37
+ align-items: center;
38
+ }
@@ -0,0 +1,93 @@
1
+ import cn from 'classnames';
2
+ import { MouseEventHandler, useEffect, useMemo, useState } from 'react';
3
+
4
+ import { CloudLogoDevSVG, CloudLogoHybridSVG, CloudLogoStageSVG, CloudLogoSVG } from '@cloud-ru/uikit-product-icons';
5
+ import { Skeleton } from '@snack-uikit/skeleton';
6
+ import { extractDataTestProps, WithSupportProps } from '@snack-uikit/utils';
7
+
8
+ import styles from './styles.module.scss';
9
+
10
+ export const HEADER_LOGO_MODE = {
11
+ develop: 'develop',
12
+ stage: 'stage',
13
+ hybrid: 'hybrid',
14
+ prod: 'prod',
15
+ } as const;
16
+
17
+ type ValueOf<T> = T[keyof T];
18
+
19
+ export type HeaderLogoMode = ValueOf<typeof HEADER_LOGO_MODE>;
20
+
21
+ export type LogoProps = WithSupportProps<{
22
+ loading?: boolean;
23
+
24
+ path?: string;
25
+
26
+ mode?: HeaderLogoMode;
27
+
28
+ href: string;
29
+
30
+ onClick?: MouseEventHandler<HTMLAnchorElement>;
31
+
32
+ className?: string;
33
+ }>;
34
+
35
+ export function Logo({ path, loading, mode, href, onClick, className, ...rest }: LogoProps) {
36
+ const [error, setError] = useState<boolean>(false);
37
+
38
+ useEffect(() => {
39
+ setError(false);
40
+ }, [path, loading]);
41
+
42
+ const logo = useMemo(() => {
43
+ if (path && !error) {
44
+ return (
45
+ <img
46
+ src={path}
47
+ alt='logo'
48
+ className={styles.logoImg}
49
+ onLoad={() => {
50
+ setError(false);
51
+ }}
52
+ onError={() => {
53
+ setError(true);
54
+ }}
55
+ />
56
+ );
57
+ }
58
+
59
+ if (mode === HEADER_LOGO_MODE.develop) {
60
+ return <CloudLogoDevSVG size={64} />;
61
+ }
62
+
63
+ if (mode === HEADER_LOGO_MODE.stage) {
64
+ return <CloudLogoStageSVG size={74} />;
65
+ }
66
+
67
+ if (mode === HEADER_LOGO_MODE.hybrid) {
68
+ return <CloudLogoHybridSVG size={78} />;
69
+ }
70
+
71
+ return <CloudLogoSVG size={24} />;
72
+ }, [error, mode, path]);
73
+
74
+ if (loading) {
75
+ return (
76
+ <div className={styles.skeletonWrapper}>
77
+ <Skeleton width={24} height={24} loading borderRadius={4} />
78
+ </div>
79
+ );
80
+ }
81
+
82
+ return (
83
+ <a
84
+ className={cn(styles.logo, className)}
85
+ href={href}
86
+ tabIndex={0}
87
+ onClick={onClick}
88
+ {...extractDataTestProps(rest)}
89
+ >
90
+ {logo}
91
+ </a>
92
+ );
93
+ }
@@ -0,0 +1 @@
1
+ export * from './Logo';
@@ -0,0 +1,30 @@
1
+ @use '@sbercloud/figma-tokens-cloud-platform/build/scss/components/styles-tokens-element' as ste;
2
+
3
+ a.logo {
4
+ display: flex;
5
+ flex-shrink: 0;
6
+ padding: ste.$dimension-1m;
7
+ cursor: pointer;
8
+ border-radius: ste.$dimension-050m;
9
+ min-width: 40px;
10
+ box-sizing: border-box;
11
+ max-height: 40px;
12
+ min-height: 40px;
13
+ align-items: center;
14
+
15
+ &:focus-visible {
16
+ @include ste.outline-var(ste.$container-focused-s);
17
+
18
+ outline-color: ste.$sys-available-complementary;
19
+ }
20
+ }
21
+
22
+ .skeletonWrapper {
23
+ padding: ste.$dimension-1m;
24
+ }
25
+
26
+ .logoImg {
27
+ width: auto;
28
+ max-height: 24px;
29
+ min-height: 24px;
30
+ }
@@ -0,0 +1,137 @@
1
+ import { MouseEvent, ReactElement, ReactNode, useCallback, useMemo } from 'react';
2
+
3
+ import { CardServiceSmall } from '@cloud-ru/uikit-product-card-predefined';
4
+ import { useLocale } from '@cloud-ru/uikit-product-locale';
5
+ import { TitleClickable } from '@cloud-ru/uikit-product-title-clickable';
6
+
7
+ import { LinksGroup } from '../types';
8
+ import styles from './styles.module.scss';
9
+
10
+ export type ContentProps = {
11
+ searchValue?: string;
12
+
13
+ serviceGroups?: LinksGroup[];
14
+
15
+ search?: ReactNode;
16
+
17
+ banners?: ReactNode;
18
+
19
+ cards?: ReactElement[];
20
+
21
+ footer?: ReactNode;
22
+
23
+ favorite?: {
24
+ value: string[];
25
+ onChange: (productId: string) => (addingValue: boolean) => void;
26
+ };
27
+
28
+ isMobile?: boolean;
29
+
30
+ initialEmpty?: boolean;
31
+
32
+ className?: string;
33
+
34
+ onLinkChange?: (value: string) => void;
35
+
36
+ onClose?(): void;
37
+ };
38
+
39
+ export function Content({
40
+ searchValue,
41
+ banners,
42
+ search,
43
+ serviceGroups,
44
+ className,
45
+ footer,
46
+ favorite,
47
+ isMobile,
48
+ onClose,
49
+ onLinkChange,
50
+ }: ContentProps) {
51
+ const { t } = useLocale('Header');
52
+
53
+ const wrappedClick = useCallback(
54
+ ({ disabled, onClick }: { disabled?: boolean; onClick?(e?: MouseEvent<HTMLElement>): void }, cb?: () => void) =>
55
+ (e?: MouseEvent<HTMLElement>) => {
56
+ if (disabled) {
57
+ e?.preventDefault();
58
+ return;
59
+ }
60
+
61
+ if (!e?.metaKey) {
62
+ e?.preventDefault();
63
+ onClose?.();
64
+ }
65
+
66
+ onClick?.(e);
67
+
68
+ cb?.();
69
+ },
70
+ [onClose],
71
+ );
72
+
73
+ const cards = useMemo(
74
+ () =>
75
+ serviceGroups?.map(({ id, label, items }) => (
76
+ <div key={String(id)} className={styles.card} id={id} data-test-id={`header__drawer-menu__group-card-${id}`}>
77
+ {!label.onClick ? (
78
+ <span className={styles.cardTitle}>{label.text}</span>
79
+ ) : (
80
+ <TitleClickable title={label.text} href='#' onClick={label.onClick} />
81
+ )}
82
+
83
+ <div className={styles.cardBody} data-mobile={isMobile || undefined}>
84
+ {items.map(service => (
85
+ <CardServiceSmall
86
+ key={String(id) + service.id}
87
+ title={service.label}
88
+ emblem={{ icon: service.icon }}
89
+ data-test-id={`header__drawer-menu__link-${service.id}`}
90
+ outline
91
+ href={service.href}
92
+ onClick={wrappedClick(service, () => onLinkChange?.(service.id))}
93
+ favorite={
94
+ favorite
95
+ ? {
96
+ checked: favorite?.value.includes(service.id),
97
+ onChange: favorite?.onChange(service.id),
98
+ visibilityStrategy: isMobile ? 'always' : 'hover',
99
+ enabled: !service.disabled,
100
+ }
101
+ : undefined
102
+ }
103
+ promoBadge={service.badge}
104
+ />
105
+ ))}
106
+ </div>
107
+ </div>
108
+ )),
109
+ [favorite, isMobile, onLinkChange, serviceGroups, wrappedClick],
110
+ );
111
+
112
+ return (
113
+ <>
114
+ {(Boolean(serviceGroups?.length) || searchValue) && search}
115
+
116
+ <div className={className}>
117
+ {!searchValue && banners}
118
+
119
+ {cards}
120
+
121
+ {!cards?.length && !searchValue && (
122
+ <div className={styles.noData} data-test-id='header__drawer-menu__no-data'>
123
+ {t('noData')}
124
+ </div>
125
+ )}
126
+
127
+ {!cards?.length && searchValue && (
128
+ <div className={styles.noData} data-test-id='header__drawer-menu__no-data-found'>
129
+ {t('noDataFound')}
130
+ </div>
131
+ )}
132
+
133
+ {footer}
134
+ </div>
135
+ </>
136
+ );
137
+ }
@@ -0,0 +1 @@
1
+ export * from './Content';