@gravity-ui/navigation 2.3.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +2 -0
  2. package/build/cjs/components/Footer/MenuItem/MenuItem.d.ts +5 -0
  3. package/build/cjs/components/Footer/desktop/Footer.d.ts +4 -0
  4. package/build/cjs/components/Footer/desktop/constants/moreItemsPopupProps.d.ts +2 -0
  5. package/build/cjs/components/Footer/desktop/index.d.ts +1 -0
  6. package/build/cjs/components/Footer/index.d.ts +3 -0
  7. package/build/cjs/components/Footer/mobile/Footer.d.ts +4 -0
  8. package/build/cjs/components/Footer/mobile/index.d.ts +1 -0
  9. package/build/cjs/components/Footer/types.d.ts +16 -0
  10. package/build/cjs/components/index.d.ts +1 -0
  11. package/build/cjs/hooks/useOverflowingHorizontalListItems/index.d.ts +1 -0
  12. package/build/cjs/hooks/useOverflowingHorizontalListItems/useOverflowingHorizontalListItems.d.ts +12 -0
  13. package/build/cjs/index.js +148 -8
  14. package/build/cjs/index.js.map +1 -1
  15. package/build/esm/components/Footer/MenuItem/MenuItem.d.ts +5 -0
  16. package/build/esm/components/Footer/desktop/Footer.d.ts +4 -0
  17. package/build/esm/components/Footer/desktop/constants/moreItemsPopupProps.d.ts +2 -0
  18. package/build/esm/components/Footer/desktop/index.d.ts +1 -0
  19. package/build/esm/components/Footer/index.d.ts +3 -0
  20. package/build/esm/components/Footer/mobile/Footer.d.ts +4 -0
  21. package/build/esm/components/Footer/mobile/index.d.ts +1 -0
  22. package/build/esm/components/Footer/types.d.ts +16 -0
  23. package/build/esm/components/index.d.ts +1 -0
  24. package/build/esm/hooks/useOverflowingHorizontalListItems/index.d.ts +1 -0
  25. package/build/esm/hooks/useOverflowingHorizontalListItems/useOverflowingHorizontalListItems.d.ts +12 -0
  26. package/build/esm/index.js +147 -8
  27. package/build/esm/index.js.map +1 -1
  28. package/package.json +1 -1
package/README.md CHANGED
@@ -29,6 +29,8 @@ npm install --dev @gravity-ui/uikit@^3.0.2 @bem-react/classname@1.6.0 react@^16.
29
29
  - AsideFallback
30
30
  - Logo
31
31
  - MobileLogo
32
+ - Footer
33
+ - MobileFooter
32
34
 
33
35
  ## Optimization
34
36
 
@@ -0,0 +1,5 @@
1
+ import type { FC } from 'react';
2
+ import { FooterMenuItem } from '../types';
3
+ import './MenuItem.scss';
4
+ export type MenuItemProps = FooterMenuItem;
5
+ export declare const MenuItem: FC<MenuItemProps>;
@@ -0,0 +1,4 @@
1
+ import type { FC } from 'react';
2
+ import { FooterProps } from '../types';
3
+ import './Footer.scss';
4
+ export declare const Footer: FC<FooterProps>;
@@ -0,0 +1,2 @@
1
+ import { PopupProps } from '@gravity-ui/uikit';
2
+ export declare const moreItemsPopupProps: PopupProps;
@@ -0,0 +1 @@
1
+ export * from './Footer';
@@ -0,0 +1,3 @@
1
+ export * from './desktop';
2
+ export * from './mobile';
3
+ export type { FooterMenuItem, FooterProps } from './types';
@@ -0,0 +1,4 @@
1
+ import type { FC } from 'react';
2
+ import { FooterProps } from '../types';
3
+ import './Footer.scss';
4
+ export declare const MobileFooter: FC<FooterProps>;
@@ -0,0 +1 @@
1
+ export * from './Footer';
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { MenuItemProps } from '@gravity-ui/uikit';
3
+ import type { LogoProps } from '../types';
4
+ export type FooterMenuItem = Omit<MenuItemProps, 'children'> & {
5
+ text: ReactNode;
6
+ };
7
+ export type FooterProps = {
8
+ className?: string;
9
+ menuItems?: FooterMenuItem[];
10
+ withDivider?: boolean;
11
+ moreButtonTitle?: string;
12
+ view?: 'normal' | 'clear';
13
+ logo?: LogoProps;
14
+ logoWrapperClassName?: string;
15
+ copyright: string;
16
+ };
@@ -13,4 +13,5 @@ export * from './Settings';
13
13
  export * from './MobileHeader';
14
14
  export * from './Logo';
15
15
  export * from './MobileLogo';
16
+ export * from './Footer';
16
17
  export * from './types';
@@ -0,0 +1 @@
1
+ export * from './useOverflowingHorizontalListItems';
@@ -0,0 +1,12 @@
1
+ import type { RefObject } from 'react';
2
+ export type UseOverflowingContainerListItemsProps<ItemType extends unknown> = {
3
+ containerRef: RefObject<HTMLElement>;
4
+ items?: ItemType[];
5
+ itemSelector: string;
6
+ moreButtonWidth?: number;
7
+ };
8
+ export declare function useOverflowingHorizontalListItems<ItemType>({ containerRef, items, itemSelector, moreButtonWidth, }: UseOverflowingContainerListItemsProps<ItemType>): {
9
+ visibleItems: ItemType[];
10
+ hiddenItems: ItemType[];
11
+ measured: boolean;
12
+ };
@@ -10,27 +10,165 @@ var PageLayout = require('./PageLayout.js');
10
10
  var PageLayoutAside = require('./PageLayoutAside-f05a501f.js');
11
11
  var AsideFallback = require('./AsideFallback.js');
12
12
  var FooterItem$1 = require('./FooterItem-f6a1d34b.js');
13
+ var React = require('react');
14
+ var uikit = require('@gravity-ui/uikit');
15
+ var debounce = require('./debounce-8772fd80.js');
16
+ var cn = require('./cn-9933321a.js');
17
+ var tslib_es6 = require('./tslib.es6-705c6589.js');
18
+ var styleInject_es = require('./style-inject.es-dcee06b6.js');
19
+ var icons = require('@gravity-ui/icons');
13
20
  var ActionBar = require('./ActionBar-38c4e24f.js');
14
21
  var Title = require('./Title-54580605.js');
15
22
  var HotkeysPanel = require('./HotkeysPanel-4ad41893.js');
16
23
  var Settings = require('./Settings-a0deac97.js');
17
- require('./tslib.es6-705c6589.js');
18
- require('react');
19
- require('@gravity-ui/uikit');
20
24
  require('react-dom');
21
- require('./cn-9933321a.js');
22
- require('@bem-react/classname');
23
- require('./style-inject.es-dcee06b6.js');
24
25
  require('./Item-27f590b7.js');
25
26
  require('./constants-d81c3867.js');
26
- require('./debounce-8772fd80.js');
27
- require('@gravity-ui/icons');
28
27
  require('./Content-64d5738a.js');
29
28
  require('./utils-db3e03c2.js');
30
29
  require('@gravity-ui/uikit/i18n');
31
30
  require('./divider-collapsed-153868e7.js');
31
+ require('@bem-react/classname');
32
+
33
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
34
+
35
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
36
+
37
+ function useOverflowingHorizontalListItems({ containerRef, items, itemSelector, moreButtonWidth = 0, }) {
38
+ const [containerWidth, setContainerWidth] = React.useState(0);
39
+ const [itemWidths, setItemWidths] = React.useState([]);
40
+ React.useLayoutEffect(() => {
41
+ if (!containerRef.current) {
42
+ return;
43
+ }
44
+ const measureItemSizes = () => {
45
+ var _a, _b;
46
+ const itemElements = Array.from((_b = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(itemSelector)) !== null && _b !== void 0 ? _b : []);
47
+ setItemWidths(itemElements.map((item) => item.clientWidth));
48
+ };
49
+ measureItemSizes();
50
+ }, [containerRef, itemSelector]);
51
+ React.useLayoutEffect(() => {
52
+ const footerMenu = containerRef.current;
53
+ if (!footerMenu) {
54
+ return;
55
+ }
56
+ const updateContainerSize = (entries) => {
57
+ if (entries.length > 0) {
58
+ setContainerWidth(entries[0].contentRect.width);
59
+ }
60
+ };
61
+ const updateContainerSizeDebounced = debounce.debounce_1(updateContainerSize, 100);
62
+ const footerMenuResizeObserver = new ResizeObserver(updateContainerSizeDebounced);
63
+ footerMenuResizeObserver.observe(footerMenu);
64
+ }, [containerRef]);
65
+ const isMeasured = containerWidth > 0;
66
+ const { visibleItems, hiddenItems } = React.useMemo(() => {
67
+ var _a, _b;
68
+ if (!isMeasured) {
69
+ return {
70
+ visibleItems: items !== null && items !== void 0 ? items : [],
71
+ hiddenItems: [],
72
+ };
73
+ }
74
+ const itemsCount = itemWidths.length;
75
+ let visibleItemsCount = 0;
76
+ let remainingContainerWidth = containerWidth;
77
+ for (const width of itemWidths) {
78
+ remainingContainerWidth -= width;
79
+ if (remainingContainerWidth < moreButtonWidth) {
80
+ const isMoreThanOneItemLeft = itemsCount !== visibleItemsCount + 1;
81
+ const hasNoSpaceForTheLastItem = remainingContainerWidth < 0;
82
+ if (isMoreThanOneItemLeft || hasNoSpaceForTheLastItem) {
83
+ break;
84
+ }
85
+ }
86
+ visibleItemsCount++;
87
+ }
88
+ return {
89
+ visibleItems: (_a = items === null || items === void 0 ? void 0 : items.slice(0, visibleItemsCount)) !== null && _a !== void 0 ? _a : [],
90
+ hiddenItems: (_b = items === null || items === void 0 ? void 0 : items.slice(visibleItemsCount)) !== null && _b !== void 0 ? _b : [],
91
+ };
92
+ }, [containerWidth, isMeasured, itemWidths, items, moreButtonWidth]);
93
+ return { visibleItems, hiddenItems, measured: isMeasured };
94
+ }
95
+
96
+ var css_248z$2 = ".gn-footer-menu-item{align-items:center;align-self:stretch;display:flex;height:100%;justify-content:center}.gn-footer-menu-item .g-menu__item-content{color:var(--g-color-text-secondary);font-size:var(--g-text-body-1-font-size);font-weight:var(--g-text-body-font-weight);line-height:var(--g-text-body-1-line-height);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gn-footer-menu-item[class]:hover{background-color:inherit}.gn-footer-menu-item[class]:hover[href] .g-menu__item-content{color:var(--g-color-text-link-hover)}";
97
+ styleInject_es.styleInject(css_248z$2);
98
+
99
+ const b$2 = cn.block('footer-menu-item');
100
+ const MenuItem = (_a) => {
101
+ var { text, className } = _a, menuItemProps = tslib_es6.__rest(_a, ["text", "className"]);
102
+ return (React__default["default"].createElement(uikit.Menu.Item, Object.assign({ className: b$2(null, className) }, menuItemProps), text));
103
+ };
104
+
105
+ const moreItemsPopupProps = {
106
+ placement: 'top-start',
107
+ };
108
+
109
+ var css_248z$1 = ".gn-footer_desktop{align-items:center;background:var(--g-color-base-background);display:flex;gap:var(--g-spacing-6);height:40px;padding:0 var(--g-spacing-6) 0 var(--g-spacing-3)}.gn-footer_desktop .gn-footer__menu{align-items:center;align-self:stretch;display:flex;flex:1;min-width:0;visibility:hidden}.gn-footer_desktop .gn-footer__menu_measured{visibility:visible}.gn-footer_desktop .gn-footer__list[class]{background-color:inherit;display:flex;height:100%;padding:0}.gn-footer_desktop .gn-footer__more-button svg{color:var(--g-color-text-secondary)}.gn-footer_desktop .gn-footer__right{align-items:center;display:flex;gap:var(--g-spacing-5)}.gn-footer_desktop .gn-footer__copyright{color:var(--g-color-text-secondary);font-size:var(--g-text-body-1-font-size);font-weight:var(--g-text-body-font-weight);line-height:var(--g-text-body-1-line-height);white-space:nowrap}.gn-footer_desktop .gn-footer__copyright_small{font-size:var(--g-text-caption-2-font-size);font-weight:var(--g-text-caption-font-weight);line-height:var(--g-text-caption-2-line-height)}.gn-footer_with-divider{border-top:1px solid var(--g-color-line-generic)}.gn-footer_view_clear{background:transparent}";
110
+ styleInject_es.styleInject(css_248z$1);
111
+
112
+ const b$1 = cn.block('footer');
113
+ const Footer = ({ className, menuItems: providedMenuItems, withDivider, moreButtonTitle, view = 'normal', logo, logoWrapperClassName, copyright, }) => {
114
+ const menuContainerRef = React.useRef(null);
115
+ const menuItems = view === 'clear' ? undefined : providedMenuItems;
116
+ const { visibleItems, hiddenItems, measured } = useOverflowingHorizontalListItems({
117
+ containerRef: menuContainerRef,
118
+ items: menuItems,
119
+ itemSelector: `.${b$1('menu-item')}`,
120
+ moreButtonWidth: 28,
121
+ });
122
+ const moreButtonProps = React.useMemo(() => ({
123
+ title: moreButtonTitle,
124
+ }), [moreButtonTitle]);
125
+ const dropdownMenuItems = React.useMemo(() => hiddenItems.map((item) => (Object.assign(Object.assign({}, item), { action: item.onClick }))), [hiddenItems]);
126
+ const shouldRenderLogo = view !== 'clear' && Boolean(logo);
127
+ return (React__default["default"].createElement("footer", { className: b$1({ desktop: true, 'with-divider': withDivider, view }, className) },
128
+ React__default["default"].createElement("div", { className: b$1('menu', { measured }), ref: menuContainerRef },
129
+ visibleItems.length > 0 && (React__default["default"].createElement(uikit.Menu, { className: b$1('list') }, visibleItems.map((item, index) => (React__default["default"].createElement(MenuItem, Object.assign({ key: index }, item, { className: b$1('menu-item', item.className) })))))),
130
+ dropdownMenuItems.length > 0 && (React__default["default"].createElement(uikit.DropdownMenu, { items: dropdownMenuItems, switcherWrapperClassName: b$1('more-button'), popupProps: moreItemsPopupProps, defaultSwitcherProps: moreButtonProps }))),
131
+ React__default["default"].createElement("div", { className: b$1('right') },
132
+ React__default["default"].createElement("small", { className: b$1('copyright', { small: !(menuItems === null || menuItems === void 0 ? void 0 : menuItems.length) }) }, copyright),
133
+ shouldRenderLogo && (React__default["default"].createElement("div", { className: logoWrapperClassName },
134
+ React__default["default"].createElement(PageLayoutAside.Logo, Object.assign({}, logo)))))));
135
+ };
32
136
 
137
+ var css_248z = ".gn-footer_mobile{background:var(--g-color-base-background);display:flex;flex-direction:column;padding:var(--g-spacing-1) var(--g-spacing-6) var(--g-spacing-3) var(--g-spacing-3)}.gn-footer_mobile .gn-footer_with-divider{border-top:1px solid var(--g-color-line-generic)}.gn-footer_mobile .gn-footer__menu{align-items:center;display:flex;justify-content:space-between;margin-bottom:var(--g-spacing-1);visibility:hidden}.gn-footer_mobile .gn-footer__menu_measured{visibility:visible}.gn-footer_mobile .gn-footer__list[class]{background-color:inherit;display:flex;padding:0}.gn-footer_mobile .gn-footer__menu-item{padding:var(--g-spacing-2) var(--g-spacing-3)}.gn-footer_mobile .gn-footer__bottom-row{align-items:center;display:flex;justify-content:space-between}.gn-footer_mobile .gn-footer__copyright{color:var(--g-color-text-secondary);font-size:var(--g-text-caption-2-font-size);font-weight:var(--g-text-caption-font-weight);line-height:var(--g-text-caption-2-line-height);padding:0 var(--g-spacing-3);white-space:nowrap}.gn-footer__modal .gn-footer__menu-item{color:var(--g-color-text-primary);font-size:var(--g-text-body-2-font-size);font-weight:var(--g-text-body-font-weight);height:48px;line-height:var(--g-text-body-2-line-height)}.gn-footer_view_clear{background:transparent}.gn-footer_view_clear .gn-footer__bottom-row{justify-content:flex-end}";
138
+ styleInject_es.styleInject(css_248z);
33
139
 
140
+ const b = cn.block('footer');
141
+ const modalId = 'footer-more-items';
142
+ const MobileFooter = ({ className, menuItems: providedMenuItems, withDivider, moreButtonTitle, view = 'normal', logo, logoWrapperClassName, copyright, }) => {
143
+ const [moreItemsMenuVisible, setMoreItemsMenuVisible] = React.useState(false);
144
+ const menuContainerRef = React.useRef(null);
145
+ const handleOpenMoreItemsMenu = React.useCallback(() => {
146
+ setMoreItemsMenuVisible(true);
147
+ }, []);
148
+ const handleCloseMoreItemsMenu = React.useCallback(() => {
149
+ setMoreItemsMenuVisible(false);
150
+ }, []);
151
+ const menuItems = view === 'clear' ? undefined : providedMenuItems;
152
+ const { visibleItems, hiddenItems, measured } = useOverflowingHorizontalListItems({
153
+ containerRef: menuContainerRef,
154
+ items: menuItems,
155
+ itemSelector: `.${b('menu-item')}`,
156
+ moreButtonWidth: 28,
157
+ });
158
+ const renderMenu = (items) => (React__default["default"].createElement(uikit.Menu, { className: b('list') }, items.map((item, index) => (React__default["default"].createElement(MenuItem, Object.assign({ key: index }, item, { className: b('menu-item', item.className) }))))));
159
+ const shouldRenderLogo = view !== 'clear' && Boolean(logo);
160
+ return (React__default["default"].createElement("footer", { className: b({ mobile: true, 'with-divider': withDivider, view }, className) },
161
+ React__default["default"].createElement("div", { className: b('menu', { measured }), ref: menuContainerRef },
162
+ visibleItems.length > 0 && renderMenu(visibleItems),
163
+ hiddenItems.length > 0 && (React__default["default"].createElement(React__default["default"].Fragment, null,
164
+ React__default["default"].createElement(uikit.Button, { view: "flat-secondary", size: "l", onClick: handleOpenMoreItemsMenu, title: moreButtonTitle },
165
+ React__default["default"].createElement(uikit.Icon, { data: icons.Ellipsis, size: 16 })),
166
+ React__default["default"].createElement(uikit.Sheet, { id: modalId, visible: moreItemsMenuVisible, className: b('modal'), contentClassName: b('modal-content'), onClose: handleCloseMoreItemsMenu }, renderMenu(hiddenItems))))),
167
+ React__default["default"].createElement("div", { className: b('bottom-row') },
168
+ React__default["default"].createElement("small", { className: b('copyright') }, copyright),
169
+ shouldRenderLogo && (React__default["default"].createElement("div", { className: logoWrapperClassName },
170
+ React__default["default"].createElement(PageLayoutAside.Logo, Object.assign({}, logo)))))));
171
+ };
34
172
 
35
173
  exports.AsideHeader = AsideHeader.AsideHeader;
36
174
  exports.AsideHeaderContextProvider = AsideHeaderContext.AsideHeaderContextProvider;
@@ -51,4 +189,6 @@ exports.HotkeysPanel = HotkeysPanel.HotkeysPanel;
51
189
  exports.Settings = Settings.Settings;
52
190
  exports.useSettingsContext = Settings.useSettingsContext;
53
191
  exports.useSettingsSelectionContext = Settings.useSettingsSelectionContext;
192
+ exports.Footer = Footer;
193
+ exports.MobileFooter = MobileFooter;
54
194
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/hooks/useOverflowingHorizontalListItems/useOverflowingHorizontalListItems.ts","../../../src/components/Footer/MenuItem/MenuItem.tsx","../../../src/components/Footer/desktop/constants/moreItemsPopupProps.ts","../../../src/components/Footer/desktop/Footer.tsx","../../../src/components/Footer/mobile/Footer.tsx"],"sourcesContent":["import {useLayoutEffect, useMemo, useState} from 'react';\nimport type {RefObject} from 'react';\n\nimport debounceFn from 'lodash/debounce';\n\nexport type UseOverflowingContainerListItemsProps<ItemType extends unknown> = {\n containerRef: RefObject<HTMLElement>;\n items?: ItemType[];\n itemSelector: string;\n moreButtonWidth?: number;\n};\n\nexport function useOverflowingHorizontalListItems<ItemType>({\n containerRef,\n items,\n itemSelector,\n moreButtonWidth = 0,\n}: UseOverflowingContainerListItemsProps<ItemType>) {\n const [containerWidth, setContainerWidth] = useState<number>(0);\n const [itemWidths, setItemWidths] = useState<number[]>([]);\n\n useLayoutEffect(() => {\n if (!containerRef.current) {\n return;\n }\n\n const measureItemSizes = () => {\n const itemElements = Array.from(\n containerRef.current?.querySelectorAll(itemSelector) ?? [],\n );\n setItemWidths(itemElements.map((item) => item.clientWidth));\n };\n\n measureItemSizes();\n }, [containerRef, itemSelector]);\n\n useLayoutEffect(() => {\n const footerMenu = containerRef.current;\n if (!footerMenu) {\n return;\n }\n\n const updateContainerSize = (entries: ResizeObserverEntry[]) => {\n if (entries.length > 0) {\n setContainerWidth(entries[0].contentRect.width);\n }\n };\n\n const updateContainerSizeDebounced = debounceFn(updateContainerSize, 100);\n const footerMenuResizeObserver = new ResizeObserver(updateContainerSizeDebounced);\n\n footerMenuResizeObserver.observe(footerMenu);\n }, [containerRef]);\n\n const isMeasured = containerWidth > 0;\n\n const {visibleItems, hiddenItems} = useMemo(() => {\n if (!isMeasured) {\n return {\n visibleItems: items ?? [],\n hiddenItems: [],\n };\n }\n\n const itemsCount = itemWidths.length;\n let visibleItemsCount = 0;\n let remainingContainerWidth = containerWidth;\n for (const width of itemWidths) {\n remainingContainerWidth -= width;\n if (remainingContainerWidth < moreButtonWidth) {\n const isMoreThanOneItemLeft = itemsCount !== visibleItemsCount + 1;\n const hasNoSpaceForTheLastItem = remainingContainerWidth < 0;\n if (isMoreThanOneItemLeft || hasNoSpaceForTheLastItem) {\n break;\n }\n }\n\n visibleItemsCount++;\n }\n\n return {\n visibleItems: items?.slice(0, visibleItemsCount) ?? [],\n hiddenItems: items?.slice(visibleItemsCount) ?? [],\n };\n }, [containerWidth, isMeasured, itemWidths, items, moreButtonWidth]);\n\n return {visibleItems, hiddenItems, measured: isMeasured};\n}\n","import React from 'react';\nimport type {FC} from 'react';\n\nimport {Menu} from '@gravity-ui/uikit';\n\nimport {block} from '../../utils/cn';\nimport {FooterMenuItem} from '../types';\n\nimport './MenuItem.scss';\n\nconst b = block('footer-menu-item');\n\nexport type MenuItemProps = FooterMenuItem;\n\nexport const MenuItem: FC<MenuItemProps> = ({text, className, ...menuItemProps}) => {\n return (\n <Menu.Item className={b(null, className)} {...menuItemProps}>\n {text}\n </Menu.Item>\n );\n};\n","import {PopupProps} from '@gravity-ui/uikit';\n\nexport const moreItemsPopupProps: PopupProps = {\n placement: 'top-start',\n};\n","import React, {useMemo, useRef} from 'react';\nimport type {FC} from 'react';\n\nimport {DropdownMenu, Menu} from '@gravity-ui/uikit';\nimport type {DropdownMenuItem} from '@gravity-ui/uikit';\n\nimport {useOverflowingHorizontalListItems} from '../../../hooks/useOverflowingHorizontalListItems';\nimport {Logo} from '../../Logo';\nimport {block} from '../../utils/cn';\nimport {MenuItem} from '../MenuItem/MenuItem';\nimport {FooterProps} from '../types';\n\nimport {moreItemsPopupProps} from './constants/moreItemsPopupProps';\n\nimport './Footer.scss';\n\nconst b = block('footer');\n\nexport const Footer: FC<FooterProps> = ({\n className,\n menuItems: providedMenuItems,\n withDivider,\n moreButtonTitle,\n view = 'normal',\n logo,\n logoWrapperClassName,\n copyright,\n}) => {\n const menuContainerRef = useRef<HTMLDivElement>(null);\n\n const menuItems = view === 'clear' ? undefined : providedMenuItems;\n\n const {visibleItems, hiddenItems, measured} = useOverflowingHorizontalListItems({\n containerRef: menuContainerRef,\n items: menuItems,\n itemSelector: `.${b('menu-item')}`,\n moreButtonWidth: 28,\n });\n\n const moreButtonProps = useMemo(\n () => ({\n title: moreButtonTitle,\n }),\n [moreButtonTitle],\n );\n\n const dropdownMenuItems = useMemo(\n () =>\n hiddenItems.map(\n (item) =>\n ({\n ...item,\n action: item.onClick,\n }) as DropdownMenuItem,\n ),\n [hiddenItems],\n );\n\n const shouldRenderLogo = view !== 'clear' && Boolean(logo);\n\n return (\n <footer className={b({desktop: true, 'with-divider': withDivider, view}, className)}>\n <div className={b('menu', {measured})} ref={menuContainerRef}>\n {visibleItems.length > 0 && (\n <Menu className={b('list')}>\n {visibleItems.map((item, index) => (\n <MenuItem\n key={index}\n {...item}\n className={b('menu-item', item.className)}\n />\n ))}\n </Menu>\n )}\n {dropdownMenuItems.length > 0 && (\n <DropdownMenu\n items={dropdownMenuItems}\n switcherWrapperClassName={b('more-button')}\n popupProps={moreItemsPopupProps}\n defaultSwitcherProps={moreButtonProps}\n />\n )}\n </div>\n <div className={b('right')}>\n <small className={b('copyright', {small: !menuItems?.length})}>{copyright}</small>\n {shouldRenderLogo && (\n <div className={logoWrapperClassName}>\n <Logo {...logo!} />\n </div>\n )}\n </div>\n </footer>\n );\n};\n","import React, {useCallback, useRef, useState} from 'react';\nimport type {FC} from 'react';\n\nimport {Ellipsis} from '@gravity-ui/icons';\nimport {Button, Icon, Menu, Sheet} from '@gravity-ui/uikit';\n\nimport {useOverflowingHorizontalListItems} from '../../../hooks/useOverflowingHorizontalListItems';\nimport {Logo} from '../../Logo';\nimport {block} from '../../utils/cn';\nimport {MenuItem} from '../MenuItem/MenuItem';\nimport {FooterMenuItem, FooterProps} from '../types';\n\nimport './Footer.scss';\n\nconst b = block('footer');\n\nconst modalId = 'footer-more-items';\n\nexport const MobileFooter: FC<FooterProps> = ({\n className,\n menuItems: providedMenuItems,\n withDivider,\n moreButtonTitle,\n view = 'normal',\n logo,\n logoWrapperClassName,\n copyright,\n}) => {\n const [moreItemsMenuVisible, setMoreItemsMenuVisible] = useState(false);\n const menuContainerRef = useRef<HTMLDivElement>(null);\n\n const handleOpenMoreItemsMenu = useCallback(() => {\n setMoreItemsMenuVisible(true);\n }, []);\n\n const handleCloseMoreItemsMenu = useCallback(() => {\n setMoreItemsMenuVisible(false);\n }, []);\n\n const menuItems = view === 'clear' ? undefined : providedMenuItems;\n\n const {visibleItems, hiddenItems, measured} = useOverflowingHorizontalListItems({\n containerRef: menuContainerRef,\n items: menuItems,\n itemSelector: `.${b('menu-item')}`,\n moreButtonWidth: 28,\n });\n\n const renderMenu = (items: FooterMenuItem[]) => (\n <Menu className={b('list')}>\n {items.map((item, index) => (\n <MenuItem key={index} {...item} className={b('menu-item', item.className)} />\n ))}\n </Menu>\n );\n\n const shouldRenderLogo = view !== 'clear' && Boolean(logo);\n\n return (\n <footer className={b({mobile: true, 'with-divider': withDivider, view}, className)}>\n <div className={b('menu', {measured})} ref={menuContainerRef}>\n {visibleItems.length > 0 && renderMenu(visibleItems)}\n {hiddenItems.length > 0 && (\n <>\n <Button\n view=\"flat-secondary\"\n size=\"l\"\n onClick={handleOpenMoreItemsMenu}\n title={moreButtonTitle}\n >\n <Icon data={Ellipsis} size={16} />\n </Button>\n <Sheet\n id={modalId}\n visible={moreItemsMenuVisible}\n className={b('modal')}\n contentClassName={b('modal-content')}\n onClose={handleCloseMoreItemsMenu}\n >\n {renderMenu(hiddenItems)}\n </Sheet>\n </>\n )}\n </div>\n <div className={b('bottom-row')}>\n <small className={b('copyright')}>{copyright}</small>\n {shouldRenderLogo && (\n <div className={logoWrapperClassName}>\n <Logo {...logo!} />\n </div>\n )}\n </div>\n </footer>\n );\n};\n"],"names":["useState","useLayoutEffect","debounceFn","useMemo","b","block","__rest","React","Menu","useRef","DropdownMenu","Logo","useCallback","Button","Icon","Ellipsis","Sheet"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { FC } from 'react';
2
+ import { FooterMenuItem } from '../types';
3
+ import './MenuItem.scss';
4
+ export type MenuItemProps = FooterMenuItem;
5
+ export declare const MenuItem: FC<MenuItemProps>;
@@ -0,0 +1,4 @@
1
+ import type { FC } from 'react';
2
+ import { FooterProps } from '../types';
3
+ import './Footer.scss';
4
+ export declare const Footer: FC<FooterProps>;
@@ -0,0 +1,2 @@
1
+ import { PopupProps } from '@gravity-ui/uikit';
2
+ export declare const moreItemsPopupProps: PopupProps;
@@ -0,0 +1 @@
1
+ export * from './Footer';
@@ -0,0 +1,3 @@
1
+ export * from './desktop';
2
+ export * from './mobile';
3
+ export type { FooterMenuItem, FooterProps } from './types';
@@ -0,0 +1,4 @@
1
+ import type { FC } from 'react';
2
+ import { FooterProps } from '../types';
3
+ import './Footer.scss';
4
+ export declare const MobileFooter: FC<FooterProps>;
@@ -0,0 +1 @@
1
+ export * from './Footer';
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from 'react';
2
+ import { MenuItemProps } from '@gravity-ui/uikit';
3
+ import type { LogoProps } from '../types';
4
+ export type FooterMenuItem = Omit<MenuItemProps, 'children'> & {
5
+ text: ReactNode;
6
+ };
7
+ export type FooterProps = {
8
+ className?: string;
9
+ menuItems?: FooterMenuItem[];
10
+ withDivider?: boolean;
11
+ moreButtonTitle?: string;
12
+ view?: 'normal' | 'clear';
13
+ logo?: LogoProps;
14
+ logoWrapperClassName?: string;
15
+ copyright: string;
16
+ };
@@ -13,4 +13,5 @@ export * from './Settings';
13
13
  export * from './MobileHeader';
14
14
  export * from './Logo';
15
15
  export * from './MobileLogo';
16
+ export * from './Footer';
16
17
  export * from './types';
@@ -0,0 +1 @@
1
+ export * from './useOverflowingHorizontalListItems';
@@ -0,0 +1,12 @@
1
+ import type { RefObject } from 'react';
2
+ export type UseOverflowingContainerListItemsProps<ItemType extends unknown> = {
3
+ containerRef: RefObject<HTMLElement>;
4
+ items?: ItemType[];
5
+ itemSelector: string;
6
+ moreButtonWidth?: number;
7
+ };
8
+ export declare function useOverflowingHorizontalListItems<ItemType>({ containerRef, items, itemSelector, moreButtonWidth, }: UseOverflowingContainerListItemsProps<ItemType>): {
9
+ visibleItems: ItemType[];
10
+ hiddenItems: ItemType[];
11
+ measured: boolean;
12
+ };
@@ -3,26 +3,165 @@ export { AsideHeaderContextProvider, useAsideHeaderContext } from './AsideHeader
3
3
  export { Drawer, DrawerItem } from './Drawer.js';
4
4
  export { FooterItem } from './FooterItem.js';
5
5
  export { PageLayout } from './PageLayout.js';
6
+ import { L as Logo } from './PageLayoutAside-39c04908.js';
6
7
  export { L as Logo, P as PageLayoutAside } from './PageLayoutAside-39c04908.js';
7
8
  export { AsideFallback } from './AsideFallback.js';
8
9
  export { M as MobileHeader, F as MobileHeaderFooterItem, a as MobileLogo } from './FooterItem-f4ec6e5b.js';
10
+ import React__default, { useState, useLayoutEffect, useMemo, useRef, useCallback } from 'react';
11
+ import { Menu, DropdownMenu, Button, Icon, Sheet } from '@gravity-ui/uikit';
12
+ import { d as debounce_1 } from './debounce-64cd2b4c.js';
13
+ import { b as block } from './cn-ffe5e9f5.js';
14
+ import { _ as __rest } from './tslib.es6-3cd4e99f.js';
15
+ import { s as styleInject } from './style-inject.es-1f59c1d0.js';
16
+ import { Ellipsis } from '@gravity-ui/icons';
9
17
  export { P as ActionBar } from './ActionBar-affc1f80.js';
10
18
  export { T as Title } from './Title-03b4255a.js';
11
19
  export { H as HotkeysPanel } from './HotkeysPanel-9138824c.js';
12
20
  export { S as Settings, a as useSettingsContext, u as useSettingsSelectionContext } from './Settings-0a78c1a7.js';
13
- import './tslib.es6-3cd4e99f.js';
14
- import 'react';
15
- import '@gravity-ui/uikit';
16
21
  import 'react-dom';
17
- import './cn-ffe5e9f5.js';
18
- import '@bem-react/classname';
19
- import './style-inject.es-1f59c1d0.js';
20
22
  import './Item-b13c32af.js';
21
23
  import './constants-b1604ff5.js';
22
- import './debounce-64cd2b4c.js';
23
- import '@gravity-ui/icons';
24
24
  import './Content-f94ba85d.js';
25
25
  import './utils-117463a5.js';
26
26
  import '@gravity-ui/uikit/i18n';
27
27
  import './divider-collapsed-6468fa36.js';
28
+ import '@bem-react/classname';
29
+
30
+ function useOverflowingHorizontalListItems({ containerRef, items, itemSelector, moreButtonWidth = 0, }) {
31
+ const [containerWidth, setContainerWidth] = useState(0);
32
+ const [itemWidths, setItemWidths] = useState([]);
33
+ useLayoutEffect(() => {
34
+ if (!containerRef.current) {
35
+ return;
36
+ }
37
+ const measureItemSizes = () => {
38
+ var _a, _b;
39
+ const itemElements = Array.from((_b = (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(itemSelector)) !== null && _b !== void 0 ? _b : []);
40
+ setItemWidths(itemElements.map((item) => item.clientWidth));
41
+ };
42
+ measureItemSizes();
43
+ }, [containerRef, itemSelector]);
44
+ useLayoutEffect(() => {
45
+ const footerMenu = containerRef.current;
46
+ if (!footerMenu) {
47
+ return;
48
+ }
49
+ const updateContainerSize = (entries) => {
50
+ if (entries.length > 0) {
51
+ setContainerWidth(entries[0].contentRect.width);
52
+ }
53
+ };
54
+ const updateContainerSizeDebounced = debounce_1(updateContainerSize, 100);
55
+ const footerMenuResizeObserver = new ResizeObserver(updateContainerSizeDebounced);
56
+ footerMenuResizeObserver.observe(footerMenu);
57
+ }, [containerRef]);
58
+ const isMeasured = containerWidth > 0;
59
+ const { visibleItems, hiddenItems } = useMemo(() => {
60
+ var _a, _b;
61
+ if (!isMeasured) {
62
+ return {
63
+ visibleItems: items !== null && items !== void 0 ? items : [],
64
+ hiddenItems: [],
65
+ };
66
+ }
67
+ const itemsCount = itemWidths.length;
68
+ let visibleItemsCount = 0;
69
+ let remainingContainerWidth = containerWidth;
70
+ for (const width of itemWidths) {
71
+ remainingContainerWidth -= width;
72
+ if (remainingContainerWidth < moreButtonWidth) {
73
+ const isMoreThanOneItemLeft = itemsCount !== visibleItemsCount + 1;
74
+ const hasNoSpaceForTheLastItem = remainingContainerWidth < 0;
75
+ if (isMoreThanOneItemLeft || hasNoSpaceForTheLastItem) {
76
+ break;
77
+ }
78
+ }
79
+ visibleItemsCount++;
80
+ }
81
+ return {
82
+ visibleItems: (_a = items === null || items === void 0 ? void 0 : items.slice(0, visibleItemsCount)) !== null && _a !== void 0 ? _a : [],
83
+ hiddenItems: (_b = items === null || items === void 0 ? void 0 : items.slice(visibleItemsCount)) !== null && _b !== void 0 ? _b : [],
84
+ };
85
+ }, [containerWidth, isMeasured, itemWidths, items, moreButtonWidth]);
86
+ return { visibleItems, hiddenItems, measured: isMeasured };
87
+ }
88
+
89
+ var css_248z$2 = ".gn-footer-menu-item{align-items:center;align-self:stretch;display:flex;height:100%;justify-content:center}.gn-footer-menu-item .g-menu__item-content{color:var(--g-color-text-secondary);font-size:var(--g-text-body-1-font-size);font-weight:var(--g-text-body-font-weight);line-height:var(--g-text-body-1-line-height);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gn-footer-menu-item[class]:hover{background-color:inherit}.gn-footer-menu-item[class]:hover[href] .g-menu__item-content{color:var(--g-color-text-link-hover)}";
90
+ styleInject(css_248z$2);
91
+
92
+ const b$2 = block('footer-menu-item');
93
+ const MenuItem = (_a) => {
94
+ var { text, className } = _a, menuItemProps = __rest(_a, ["text", "className"]);
95
+ return (React__default.createElement(Menu.Item, Object.assign({ className: b$2(null, className) }, menuItemProps), text));
96
+ };
97
+
98
+ const moreItemsPopupProps = {
99
+ placement: 'top-start',
100
+ };
101
+
102
+ var css_248z$1 = ".gn-footer_desktop{align-items:center;background:var(--g-color-base-background);display:flex;gap:var(--g-spacing-6);height:40px;padding:0 var(--g-spacing-6) 0 var(--g-spacing-3)}.gn-footer_desktop .gn-footer__menu{align-items:center;align-self:stretch;display:flex;flex:1;min-width:0;visibility:hidden}.gn-footer_desktop .gn-footer__menu_measured{visibility:visible}.gn-footer_desktop .gn-footer__list[class]{background-color:inherit;display:flex;height:100%;padding:0}.gn-footer_desktop .gn-footer__more-button svg{color:var(--g-color-text-secondary)}.gn-footer_desktop .gn-footer__right{align-items:center;display:flex;gap:var(--g-spacing-5)}.gn-footer_desktop .gn-footer__copyright{color:var(--g-color-text-secondary);font-size:var(--g-text-body-1-font-size);font-weight:var(--g-text-body-font-weight);line-height:var(--g-text-body-1-line-height);white-space:nowrap}.gn-footer_desktop .gn-footer__copyright_small{font-size:var(--g-text-caption-2-font-size);font-weight:var(--g-text-caption-font-weight);line-height:var(--g-text-caption-2-line-height)}.gn-footer_with-divider{border-top:1px solid var(--g-color-line-generic)}.gn-footer_view_clear{background:transparent}";
103
+ styleInject(css_248z$1);
104
+
105
+ const b$1 = block('footer');
106
+ const Footer = ({ className, menuItems: providedMenuItems, withDivider, moreButtonTitle, view = 'normal', logo, logoWrapperClassName, copyright, }) => {
107
+ const menuContainerRef = useRef(null);
108
+ const menuItems = view === 'clear' ? undefined : providedMenuItems;
109
+ const { visibleItems, hiddenItems, measured } = useOverflowingHorizontalListItems({
110
+ containerRef: menuContainerRef,
111
+ items: menuItems,
112
+ itemSelector: `.${b$1('menu-item')}`,
113
+ moreButtonWidth: 28,
114
+ });
115
+ const moreButtonProps = useMemo(() => ({
116
+ title: moreButtonTitle,
117
+ }), [moreButtonTitle]);
118
+ const dropdownMenuItems = useMemo(() => hiddenItems.map((item) => (Object.assign(Object.assign({}, item), { action: item.onClick }))), [hiddenItems]);
119
+ const shouldRenderLogo = view !== 'clear' && Boolean(logo);
120
+ return (React__default.createElement("footer", { className: b$1({ desktop: true, 'with-divider': withDivider, view }, className) },
121
+ React__default.createElement("div", { className: b$1('menu', { measured }), ref: menuContainerRef },
122
+ visibleItems.length > 0 && (React__default.createElement(Menu, { className: b$1('list') }, visibleItems.map((item, index) => (React__default.createElement(MenuItem, Object.assign({ key: index }, item, { className: b$1('menu-item', item.className) })))))),
123
+ dropdownMenuItems.length > 0 && (React__default.createElement(DropdownMenu, { items: dropdownMenuItems, switcherWrapperClassName: b$1('more-button'), popupProps: moreItemsPopupProps, defaultSwitcherProps: moreButtonProps }))),
124
+ React__default.createElement("div", { className: b$1('right') },
125
+ React__default.createElement("small", { className: b$1('copyright', { small: !(menuItems === null || menuItems === void 0 ? void 0 : menuItems.length) }) }, copyright),
126
+ shouldRenderLogo && (React__default.createElement("div", { className: logoWrapperClassName },
127
+ React__default.createElement(Logo, Object.assign({}, logo)))))));
128
+ };
129
+
130
+ var css_248z = ".gn-footer_mobile{background:var(--g-color-base-background);display:flex;flex-direction:column;padding:var(--g-spacing-1) var(--g-spacing-6) var(--g-spacing-3) var(--g-spacing-3)}.gn-footer_mobile .gn-footer_with-divider{border-top:1px solid var(--g-color-line-generic)}.gn-footer_mobile .gn-footer__menu{align-items:center;display:flex;justify-content:space-between;margin-bottom:var(--g-spacing-1);visibility:hidden}.gn-footer_mobile .gn-footer__menu_measured{visibility:visible}.gn-footer_mobile .gn-footer__list[class]{background-color:inherit;display:flex;padding:0}.gn-footer_mobile .gn-footer__menu-item{padding:var(--g-spacing-2) var(--g-spacing-3)}.gn-footer_mobile .gn-footer__bottom-row{align-items:center;display:flex;justify-content:space-between}.gn-footer_mobile .gn-footer__copyright{color:var(--g-color-text-secondary);font-size:var(--g-text-caption-2-font-size);font-weight:var(--g-text-caption-font-weight);line-height:var(--g-text-caption-2-line-height);padding:0 var(--g-spacing-3);white-space:nowrap}.gn-footer__modal .gn-footer__menu-item{color:var(--g-color-text-primary);font-size:var(--g-text-body-2-font-size);font-weight:var(--g-text-body-font-weight);height:48px;line-height:var(--g-text-body-2-line-height)}.gn-footer_view_clear{background:transparent}.gn-footer_view_clear .gn-footer__bottom-row{justify-content:flex-end}";
131
+ styleInject(css_248z);
132
+
133
+ const b = block('footer');
134
+ const modalId = 'footer-more-items';
135
+ const MobileFooter = ({ className, menuItems: providedMenuItems, withDivider, moreButtonTitle, view = 'normal', logo, logoWrapperClassName, copyright, }) => {
136
+ const [moreItemsMenuVisible, setMoreItemsMenuVisible] = useState(false);
137
+ const menuContainerRef = useRef(null);
138
+ const handleOpenMoreItemsMenu = useCallback(() => {
139
+ setMoreItemsMenuVisible(true);
140
+ }, []);
141
+ const handleCloseMoreItemsMenu = useCallback(() => {
142
+ setMoreItemsMenuVisible(false);
143
+ }, []);
144
+ const menuItems = view === 'clear' ? undefined : providedMenuItems;
145
+ const { visibleItems, hiddenItems, measured } = useOverflowingHorizontalListItems({
146
+ containerRef: menuContainerRef,
147
+ items: menuItems,
148
+ itemSelector: `.${b('menu-item')}`,
149
+ moreButtonWidth: 28,
150
+ });
151
+ const renderMenu = (items) => (React__default.createElement(Menu, { className: b('list') }, items.map((item, index) => (React__default.createElement(MenuItem, Object.assign({ key: index }, item, { className: b('menu-item', item.className) }))))));
152
+ const shouldRenderLogo = view !== 'clear' && Boolean(logo);
153
+ return (React__default.createElement("footer", { className: b({ mobile: true, 'with-divider': withDivider, view }, className) },
154
+ React__default.createElement("div", { className: b('menu', { measured }), ref: menuContainerRef },
155
+ visibleItems.length > 0 && renderMenu(visibleItems),
156
+ hiddenItems.length > 0 && (React__default.createElement(React__default.Fragment, null,
157
+ React__default.createElement(Button, { view: "flat-secondary", size: "l", onClick: handleOpenMoreItemsMenu, title: moreButtonTitle },
158
+ React__default.createElement(Icon, { data: Ellipsis, size: 16 })),
159
+ React__default.createElement(Sheet, { id: modalId, visible: moreItemsMenuVisible, className: b('modal'), contentClassName: b('modal-content'), onClose: handleCloseMoreItemsMenu }, renderMenu(hiddenItems))))),
160
+ React__default.createElement("div", { className: b('bottom-row') },
161
+ React__default.createElement("small", { className: b('copyright') }, copyright),
162
+ shouldRenderLogo && (React__default.createElement("div", { className: logoWrapperClassName },
163
+ React__default.createElement(Logo, Object.assign({}, logo)))))));
164
+ };
165
+
166
+ export { Footer, MobileFooter };
28
167
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/hooks/useOverflowingHorizontalListItems/useOverflowingHorizontalListItems.ts","../../../src/components/Footer/MenuItem/MenuItem.tsx","../../../src/components/Footer/desktop/constants/moreItemsPopupProps.ts","../../../src/components/Footer/desktop/Footer.tsx","../../../src/components/Footer/mobile/Footer.tsx"],"sourcesContent":["import {useLayoutEffect, useMemo, useState} from 'react';\nimport type {RefObject} from 'react';\n\nimport debounceFn from 'lodash/debounce';\n\nexport type UseOverflowingContainerListItemsProps<ItemType extends unknown> = {\n containerRef: RefObject<HTMLElement>;\n items?: ItemType[];\n itemSelector: string;\n moreButtonWidth?: number;\n};\n\nexport function useOverflowingHorizontalListItems<ItemType>({\n containerRef,\n items,\n itemSelector,\n moreButtonWidth = 0,\n}: UseOverflowingContainerListItemsProps<ItemType>) {\n const [containerWidth, setContainerWidth] = useState<number>(0);\n const [itemWidths, setItemWidths] = useState<number[]>([]);\n\n useLayoutEffect(() => {\n if (!containerRef.current) {\n return;\n }\n\n const measureItemSizes = () => {\n const itemElements = Array.from(\n containerRef.current?.querySelectorAll(itemSelector) ?? [],\n );\n setItemWidths(itemElements.map((item) => item.clientWidth));\n };\n\n measureItemSizes();\n }, [containerRef, itemSelector]);\n\n useLayoutEffect(() => {\n const footerMenu = containerRef.current;\n if (!footerMenu) {\n return;\n }\n\n const updateContainerSize = (entries: ResizeObserverEntry[]) => {\n if (entries.length > 0) {\n setContainerWidth(entries[0].contentRect.width);\n }\n };\n\n const updateContainerSizeDebounced = debounceFn(updateContainerSize, 100);\n const footerMenuResizeObserver = new ResizeObserver(updateContainerSizeDebounced);\n\n footerMenuResizeObserver.observe(footerMenu);\n }, [containerRef]);\n\n const isMeasured = containerWidth > 0;\n\n const {visibleItems, hiddenItems} = useMemo(() => {\n if (!isMeasured) {\n return {\n visibleItems: items ?? [],\n hiddenItems: [],\n };\n }\n\n const itemsCount = itemWidths.length;\n let visibleItemsCount = 0;\n let remainingContainerWidth = containerWidth;\n for (const width of itemWidths) {\n remainingContainerWidth -= width;\n if (remainingContainerWidth < moreButtonWidth) {\n const isMoreThanOneItemLeft = itemsCount !== visibleItemsCount + 1;\n const hasNoSpaceForTheLastItem = remainingContainerWidth < 0;\n if (isMoreThanOneItemLeft || hasNoSpaceForTheLastItem) {\n break;\n }\n }\n\n visibleItemsCount++;\n }\n\n return {\n visibleItems: items?.slice(0, visibleItemsCount) ?? [],\n hiddenItems: items?.slice(visibleItemsCount) ?? [],\n };\n }, [containerWidth, isMeasured, itemWidths, items, moreButtonWidth]);\n\n return {visibleItems, hiddenItems, measured: isMeasured};\n}\n","import React from 'react';\nimport type {FC} from 'react';\n\nimport {Menu} from '@gravity-ui/uikit';\n\nimport {block} from '../../utils/cn';\nimport {FooterMenuItem} from '../types';\n\nimport './MenuItem.scss';\n\nconst b = block('footer-menu-item');\n\nexport type MenuItemProps = FooterMenuItem;\n\nexport const MenuItem: FC<MenuItemProps> = ({text, className, ...menuItemProps}) => {\n return (\n <Menu.Item className={b(null, className)} {...menuItemProps}>\n {text}\n </Menu.Item>\n );\n};\n","import {PopupProps} from '@gravity-ui/uikit';\n\nexport const moreItemsPopupProps: PopupProps = {\n placement: 'top-start',\n};\n","import React, {useMemo, useRef} from 'react';\nimport type {FC} from 'react';\n\nimport {DropdownMenu, Menu} from '@gravity-ui/uikit';\nimport type {DropdownMenuItem} from '@gravity-ui/uikit';\n\nimport {useOverflowingHorizontalListItems} from '../../../hooks/useOverflowingHorizontalListItems';\nimport {Logo} from '../../Logo';\nimport {block} from '../../utils/cn';\nimport {MenuItem} from '../MenuItem/MenuItem';\nimport {FooterProps} from '../types';\n\nimport {moreItemsPopupProps} from './constants/moreItemsPopupProps';\n\nimport './Footer.scss';\n\nconst b = block('footer');\n\nexport const Footer: FC<FooterProps> = ({\n className,\n menuItems: providedMenuItems,\n withDivider,\n moreButtonTitle,\n view = 'normal',\n logo,\n logoWrapperClassName,\n copyright,\n}) => {\n const menuContainerRef = useRef<HTMLDivElement>(null);\n\n const menuItems = view === 'clear' ? undefined : providedMenuItems;\n\n const {visibleItems, hiddenItems, measured} = useOverflowingHorizontalListItems({\n containerRef: menuContainerRef,\n items: menuItems,\n itemSelector: `.${b('menu-item')}`,\n moreButtonWidth: 28,\n });\n\n const moreButtonProps = useMemo(\n () => ({\n title: moreButtonTitle,\n }),\n [moreButtonTitle],\n );\n\n const dropdownMenuItems = useMemo(\n () =>\n hiddenItems.map(\n (item) =>\n ({\n ...item,\n action: item.onClick,\n }) as DropdownMenuItem,\n ),\n [hiddenItems],\n );\n\n const shouldRenderLogo = view !== 'clear' && Boolean(logo);\n\n return (\n <footer className={b({desktop: true, 'with-divider': withDivider, view}, className)}>\n <div className={b('menu', {measured})} ref={menuContainerRef}>\n {visibleItems.length > 0 && (\n <Menu className={b('list')}>\n {visibleItems.map((item, index) => (\n <MenuItem\n key={index}\n {...item}\n className={b('menu-item', item.className)}\n />\n ))}\n </Menu>\n )}\n {dropdownMenuItems.length > 0 && (\n <DropdownMenu\n items={dropdownMenuItems}\n switcherWrapperClassName={b('more-button')}\n popupProps={moreItemsPopupProps}\n defaultSwitcherProps={moreButtonProps}\n />\n )}\n </div>\n <div className={b('right')}>\n <small className={b('copyright', {small: !menuItems?.length})}>{copyright}</small>\n {shouldRenderLogo && (\n <div className={logoWrapperClassName}>\n <Logo {...logo!} />\n </div>\n )}\n </div>\n </footer>\n );\n};\n","import React, {useCallback, useRef, useState} from 'react';\nimport type {FC} from 'react';\n\nimport {Ellipsis} from '@gravity-ui/icons';\nimport {Button, Icon, Menu, Sheet} from '@gravity-ui/uikit';\n\nimport {useOverflowingHorizontalListItems} from '../../../hooks/useOverflowingHorizontalListItems';\nimport {Logo} from '../../Logo';\nimport {block} from '../../utils/cn';\nimport {MenuItem} from '../MenuItem/MenuItem';\nimport {FooterMenuItem, FooterProps} from '../types';\n\nimport './Footer.scss';\n\nconst b = block('footer');\n\nconst modalId = 'footer-more-items';\n\nexport const MobileFooter: FC<FooterProps> = ({\n className,\n menuItems: providedMenuItems,\n withDivider,\n moreButtonTitle,\n view = 'normal',\n logo,\n logoWrapperClassName,\n copyright,\n}) => {\n const [moreItemsMenuVisible, setMoreItemsMenuVisible] = useState(false);\n const menuContainerRef = useRef<HTMLDivElement>(null);\n\n const handleOpenMoreItemsMenu = useCallback(() => {\n setMoreItemsMenuVisible(true);\n }, []);\n\n const handleCloseMoreItemsMenu = useCallback(() => {\n setMoreItemsMenuVisible(false);\n }, []);\n\n const menuItems = view === 'clear' ? undefined : providedMenuItems;\n\n const {visibleItems, hiddenItems, measured} = useOverflowingHorizontalListItems({\n containerRef: menuContainerRef,\n items: menuItems,\n itemSelector: `.${b('menu-item')}`,\n moreButtonWidth: 28,\n });\n\n const renderMenu = (items: FooterMenuItem[]) => (\n <Menu className={b('list')}>\n {items.map((item, index) => (\n <MenuItem key={index} {...item} className={b('menu-item', item.className)} />\n ))}\n </Menu>\n );\n\n const shouldRenderLogo = view !== 'clear' && Boolean(logo);\n\n return (\n <footer className={b({mobile: true, 'with-divider': withDivider, view}, className)}>\n <div className={b('menu', {measured})} ref={menuContainerRef}>\n {visibleItems.length > 0 && renderMenu(visibleItems)}\n {hiddenItems.length > 0 && (\n <>\n <Button\n view=\"flat-secondary\"\n size=\"l\"\n onClick={handleOpenMoreItemsMenu}\n title={moreButtonTitle}\n >\n <Icon data={Ellipsis} size={16} />\n </Button>\n <Sheet\n id={modalId}\n visible={moreItemsMenuVisible}\n className={b('modal')}\n contentClassName={b('modal-content')}\n onClose={handleCloseMoreItemsMenu}\n >\n {renderMenu(hiddenItems)}\n </Sheet>\n </>\n )}\n </div>\n <div className={b('bottom-row')}>\n <small className={b('copyright')}>{copyright}</small>\n {shouldRenderLogo && (\n <div className={logoWrapperClassName}>\n <Logo {...logo!} />\n </div>\n )}\n </div>\n </footer>\n );\n};\n"],"names":["debounceFn","b","React"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/navigation",
3
- "version": "2.3.1",
3
+ "version": "2.4.0",
4
4
  "description": "Gravity UI Navigation components",
5
5
  "license": "MIT",
6
6
  "repository": {