@gravity-ui/navigation 6.1.2 → 6.3.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.
- package/README.md +64 -0
- package/build/cjs/components/AsideHeader/components/FirstPanel.js +2 -1
- package/build/cjs/components/AsideHeader/components/FirstPanel.js.map +1 -1
- package/build/cjs/components/AsideHeader/types.d.ts +1 -0
- package/build/cjs/components/AsideHeader/types.js.map +1 -1
- package/build/docs/INDEX.md +89 -0
- package/build/docs/components/ActionBar.md +152 -0
- package/build/docs/components/AsideHeader/components/AllPagesPanel.md +80 -0
- package/build/docs/components/AsideHeader.md +351 -0
- package/build/docs/components/Footer.md +114 -0
- package/build/docs/components/HotkeysPanel.md +46 -0
- package/build/docs/components/Logo.md +22 -0
- package/build/docs/components/MobileHeader.md +82 -0
- package/build/docs/components/Settings.md +113 -0
- package/build/docs/hooks/useOverflowingHorizontalListItems.md +16 -0
- package/build/esm/components/AsideHeader/components/FirstPanel.js +2 -1
- package/build/esm/components/AsideHeader/components/FirstPanel.js.map +1 -1
- package/build/esm/components/AsideHeader/types.d.ts +1 -0
- package/build/esm/components/AsideHeader/types.js.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -16,6 +16,38 @@ Ensure that peer dependencies are installed in your project
|
|
|
16
16
|
npm install --dev @gravity-ui/uikit@^7.2.0 @gravity-ui/icons@^2.2.0 @bem-react/classname@^1.6.0 react@^19.0.0 react-dom@^19.0.0
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Render `AsideHeader` as the app shell. It is a controlled component — you own the collapsed state via `compact`/`onChangeCompact` — and your page content goes through `renderContent`. Set up `@gravity-ui/uikit` styles and `ThemeProvider` first (see the [uikit styles guide](https://github.com/gravity-ui/uikit?tab=readme-ov-file#styles)).
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import React from 'react';
|
|
25
|
+
import {AsideHeader} from '@gravity-ui/navigation';
|
|
26
|
+
import {Gear, House} from '@gravity-ui/icons';
|
|
27
|
+
import {ThemeProvider} from '@gravity-ui/uikit';
|
|
28
|
+
|
|
29
|
+
import '@gravity-ui/uikit/styles/styles.css';
|
|
30
|
+
|
|
31
|
+
export function App() {
|
|
32
|
+
const [compact, setCompact] = React.useState(false);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<ThemeProvider theme="light">
|
|
36
|
+
<AsideHeader
|
|
37
|
+
logo={{text: 'My App', href: '/'}}
|
|
38
|
+
compact={compact}
|
|
39
|
+
onChangeCompact={setCompact}
|
|
40
|
+
menuItems={[
|
|
41
|
+
{id: 'home', title: 'Home', icon: House, current: true},
|
|
42
|
+
{id: 'settings', title: 'Settings', icon: Gear},
|
|
43
|
+
]}
|
|
44
|
+
renderContent={() => <main>Page content</main>}
|
|
45
|
+
/>
|
|
46
|
+
</ThemeProvider>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
19
51
|
## Sandboxes
|
|
20
52
|
|
|
21
53
|
Basic
|
|
@@ -54,3 +86,35 @@ https://codesandbox.io/p/devbox/recursing-dawn-6kc9vh
|
|
|
54
86
|
## CSS API
|
|
55
87
|
|
|
56
88
|
Used for themization Navigation's components
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
Distributed under the MIT License. See [LICENSE](LICENSE) for details.
|
|
93
|
+
|
|
94
|
+
## For AI agents
|
|
95
|
+
|
|
96
|
+
Application-shell navigation components for Gravity UI apps — the collapsible `AsideHeader` sidebar plus footers, drawers, logo, hotkeys and settings panels that frame a whole page.
|
|
97
|
+
|
|
98
|
+
### When to use
|
|
99
|
+
|
|
100
|
+
- The app's primary navigation frame: `AsideHeader` (collapsible side navigation) with `menuItems`, subheader, and footer sections.
|
|
101
|
+
- Supporting shell UI: `Drawer`/`DrawerItem`, `Footer`/`MobileFooter`, `MobileHeader`, `HotkeysPanel`, `Settings`, `ActionBar`, `Logo`.
|
|
102
|
+
- Laying out page content inside the navigation frame via `renderContent` / `PageLayout`.
|
|
103
|
+
|
|
104
|
+
### When not to use
|
|
105
|
+
|
|
106
|
+
- Generic in-page controls (buttons, tabs, menus, breadcrumbs) — use [`@gravity-ui/uikit`](https://github.com/gravity-ui/uikit); this package is the outer app chrome, not general components.
|
|
107
|
+
- Rendering the page body itself from config — use [`@gravity-ui/page-constructor`](https://github.com/gravity-ui/page-constructor).
|
|
108
|
+
- Client-side routing — this provides the navigation UI only; wire clicks to your own router.
|
|
109
|
+
|
|
110
|
+
### Common pitfalls
|
|
111
|
+
|
|
112
|
+
- **`AsideHeader` is controlled.** You must own the collapsed state with `compact` and update it in `onChangeCompact`; passing `compact` without the handler freezes the sidebar.
|
|
113
|
+
- **Menu items are `menuItems`, keyed by `id`.** Each item is `{id, title, icon, current, onItemClick}`; `icon` takes an icon component (e.g. from `@gravity-ui/icons`), not a string name.
|
|
114
|
+
- **Peer dependencies are required.** `@gravity-ui/uikit`, `@gravity-ui/icons`, and `@bem-react/classname` must be installed alongside `react`/`react-dom`.
|
|
115
|
+
- **Needs uikit setup.** Render inside `ThemeProvider` and import `@gravity-ui/uikit/styles/styles.css`, or the shell renders unstyled.
|
|
116
|
+
- **Page content goes through `renderContent`.** Render your routed content via the `renderContent` prop / `PageLayout`, not as `children`.
|
|
117
|
+
|
|
118
|
+
## Documentation for AI agents
|
|
119
|
+
|
|
120
|
+
Agent-readable documentation for the installed version is located in `node_modules/@gravity-ui/navigation/build/docs/INDEX.md`.
|
|
@@ -17,7 +17,7 @@ var Panels = require('./Panels.js');
|
|
|
17
17
|
|
|
18
18
|
const MENU_ITEMS_COMPOSITE_ID = 'gravity-ui/navigation-menu-items-composite-bar';
|
|
19
19
|
const FirstPanel = React.forwardRef((_props, ref) => {
|
|
20
|
-
const { size, onItemClick, headerDecoration, menuMoreTitle, onMenuMoreClick, renderFooter, compact, customBackground, customBackgroundClassName, className, hideCollapseButton, menuGroups, menuOverflow, collapsedMenuGroupIds, defaultCollapsedMenuGroupIds, onToggleMenuGroupCollapsed, qa, } = AsideHeaderContext.useAsideHeaderInnerContext();
|
|
20
|
+
const { size, onItemClick, headerDecoration, menuMoreTitle, onMenuMoreClick, renderFooter, compact, customBackground, customBackgroundClassName, className, hideCollapseButton, menuGroups, menuOverflow, collapsedMenuGroupIds, defaultCollapsedMenuGroupIds, onToggleMenuGroupCollapsed, aboveMenuContent, qa, } = AsideHeaderContext.useAsideHeaderInnerContext();
|
|
21
21
|
const visibleMenuItems = useVisibleMenuItems.useVisibleMenuItems();
|
|
22
22
|
const asideRef = React.useRef(null);
|
|
23
23
|
React.useEffect(() => {
|
|
@@ -29,6 +29,7 @@ const FirstPanel = React.forwardRef((_props, ref) => {
|
|
|
29
29
|
customBackground && (React.createElement("div", { className: utils.b('aside-custom-background', customBackgroundClassName) }, customBackground)),
|
|
30
30
|
React.createElement("div", { className: utils.b('aside-content', { ['with-decoration']: headerDecoration }) },
|
|
31
31
|
React.createElement(Header.Header, null),
|
|
32
|
+
aboveMenuContent,
|
|
32
33
|
(visibleMenuItems === null || visibleMenuItems === undefined ? undefined : visibleMenuItems.length) ? (React.createElement(CompositeBar.CompositeBar, { menuItemClassName: utils.b('menu-item'), compositeId: MENU_ITEMS_COMPOSITE_ID, type: "menu", compact: compact, items: visibleMenuItems, menuGroups: menuGroups, menuMoreTitle: menuMoreTitle !== null && menuMoreTitle !== undefined ? menuMoreTitle : index.default('label_more'), onItemClick: onItemClick, onMoreClick: onMenuMoreClick, menuOverflow: menuOverflow, collapsedMenuGroupIds: collapsedMenuGroupIds, defaultCollapsedMenuGroupIds: defaultCollapsedMenuGroupIds, onToggleMenuGroupCollapsed: onToggleMenuGroupCollapsed })) : (React.createElement("div", { className: utils.b('menu-items') })),
|
|
33
34
|
React.createElement("div", { className: utils.b('footer') }, renderFooter === null || renderFooter === undefined ? undefined : renderFooter({
|
|
34
35
|
size,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirstPanel.js","sources":["../../../../../../src/components/AsideHeader/components/FirstPanel.tsx"],"sourcesContent":["import React, {useRef} from 'react';\n\nimport {setRef} from '@gravity-ui/uikit';\n\nimport {useAsideHeaderInnerContext} from '../AsideHeaderContext';\nimport i18n from '../i18n';\nimport {b} from '../utils';\n\nimport {useVisibleMenuItems} from './AllPagesPanel';\nimport {CollapseButton} from './CollapseButton/CollapseButton';\nimport {CompositeBar} from './CompositeBar';\nimport {Header} from './Header';\nimport {Panels} from './Panels';\n\nconst MENU_ITEMS_COMPOSITE_ID = 'gravity-ui/navigation-menu-items-composite-bar';\n\nexport const FirstPanel = React.forwardRef<HTMLDivElement>((_props, ref) => {\n const {\n size,\n onItemClick,\n headerDecoration,\n menuMoreTitle,\n onMenuMoreClick,\n renderFooter,\n compact,\n customBackground,\n customBackgroundClassName,\n className,\n hideCollapseButton,\n menuGroups,\n menuOverflow,\n collapsedMenuGroupIds,\n defaultCollapsedMenuGroupIds,\n onToggleMenuGroupCollapsed,\n qa,\n } = useAsideHeaderInnerContext();\n const visibleMenuItems = useVisibleMenuItems();\n\n const asideRef = useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n setRef<HTMLDivElement>(ref, asideRef.current);\n }, [ref]);\n\n return (\n <React.Fragment>\n <div\n className={b(\n 'aside',\n {'menu-overflow-scroll': menuOverflow === 'scroll' && !compact},\n className,\n )}\n style={{width: size}}\n data-qa={qa}\n >\n <div className={b('aside-popup-anchor')} ref={asideRef} />\n {customBackground && (\n <div className={b('aside-custom-background', customBackgroundClassName)}>\n {customBackground}\n </div>\n )}\n\n <div className={b('aside-content', {['with-decoration']: headerDecoration})}>\n <Header />\n {visibleMenuItems?.length ? (\n <CompositeBar\n menuItemClassName={b('menu-item')}\n compositeId={MENU_ITEMS_COMPOSITE_ID}\n type=\"menu\"\n compact={compact}\n items={visibleMenuItems}\n menuGroups={menuGroups}\n menuMoreTitle={menuMoreTitle ?? i18n('label_more')}\n onItemClick={onItemClick}\n onMoreClick={onMenuMoreClick}\n menuOverflow={menuOverflow}\n collapsedMenuGroupIds={collapsedMenuGroupIds}\n defaultCollapsedMenuGroupIds={defaultCollapsedMenuGroupIds}\n onToggleMenuGroupCollapsed={onToggleMenuGroupCollapsed}\n />\n ) : (\n <div className={b('menu-items')} />\n )}\n <div className={b('footer')}>\n {renderFooter?.({\n size,\n compact: Boolean(compact),\n asideRef,\n })}\n </div>\n {!hideCollapseButton && <CollapseButton />}\n </div>\n </div>\n <Panels />\n </React.Fragment>\n );\n});\n\nFirstPanel.displayName = 'FirstPanel';\n"],"names":["useAsideHeaderInnerContext","useVisibleMenuItems","useRef","setRef","b","Header","CompositeBar","i18n","CollapseButton","Panels"],"mappings":";;;;;;;;;;;;;;;;;AAcA,MAAM,uBAAuB,GAAG,gDAAgD;AAEzE,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAiB,CAAC,MAAM,EAAE,GAAG,KAAI;AACvE,IAAA,MAAM,EACF,IAAI,EACJ,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,yBAAyB,EACzB,SAAS,EACT,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,4BAA4B,EAC5B,0BAA0B,EAC1B,EAAE,GACL,GAAGA,6CAA0B,EAAE;AAChC,IAAA,MAAM,gBAAgB,GAAGC,uCAAmB,EAAE;AAE9C,IAAA,MAAM,QAAQ,GAAGC,YAAM,CAAiB,IAAI,CAAC;AAE7C,IAAA,KAAK,CAAC,SAAS,CAAC,MAAK;AACjB,QAAAC,YAAM,CAAiB,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC;AACjD,KAAC,EAAE,CAAC,GAAG,CAAC,CAAC;AAET,IAAA,QACI,KAAA,CAAA,aAAA,CAAC,KAAK,CAAC,QAAQ,EAAA,IAAA;AACX,QAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EACI,SAAS,EAAEC,OAAC,CACR,OAAO,EACP,EAAC,sBAAsB,EAAE,YAAY,KAAK,QAAQ,IAAI,CAAC,OAAO,EAAC,EAC/D,SAAS,CACZ,EACD,KAAK,EAAE,EAAC,KAAK,EAAE,IAAI,EAAC,EAAA,SAAA,EACX,EAAE,EAAA;YAEX,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAEA,OAAC,CAAC,oBAAoB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAI,CAAA;AACzD,YAAA,gBAAgB,KACb,KAAK,CAAA,aAAA,CAAA,KAAA,EAAA,EAAA,SAAS,EAAEA,OAAC,CAAC,yBAAyB,EAAE,yBAAyB,CAAC,EAClE,EAAA,gBAAgB,CACf,CACT;AAED,YAAA,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAEA,OAAC,CAAC,eAAe,EAAE,EAAC,CAAC,iBAAiB,GAAG,gBAAgB,EAAC,CAAC,EAAA;AACvE,gBAAA,KAAA,CAAA,aAAA,CAACC,aAAM,EAAG,IAAA,CAAA;
|
|
1
|
+
{"version":3,"file":"FirstPanel.js","sources":["../../../../../../src/components/AsideHeader/components/FirstPanel.tsx"],"sourcesContent":["import React, {useRef} from 'react';\n\nimport {setRef} from '@gravity-ui/uikit';\n\nimport {useAsideHeaderInnerContext} from '../AsideHeaderContext';\nimport i18n from '../i18n';\nimport {b} from '../utils';\n\nimport {useVisibleMenuItems} from './AllPagesPanel';\nimport {CollapseButton} from './CollapseButton/CollapseButton';\nimport {CompositeBar} from './CompositeBar';\nimport {Header} from './Header';\nimport {Panels} from './Panels';\n\nconst MENU_ITEMS_COMPOSITE_ID = 'gravity-ui/navigation-menu-items-composite-bar';\n\nexport const FirstPanel = React.forwardRef<HTMLDivElement>((_props, ref) => {\n const {\n size,\n onItemClick,\n headerDecoration,\n menuMoreTitle,\n onMenuMoreClick,\n renderFooter,\n compact,\n customBackground,\n customBackgroundClassName,\n className,\n hideCollapseButton,\n menuGroups,\n menuOverflow,\n collapsedMenuGroupIds,\n defaultCollapsedMenuGroupIds,\n onToggleMenuGroupCollapsed,\n aboveMenuContent,\n qa,\n } = useAsideHeaderInnerContext();\n const visibleMenuItems = useVisibleMenuItems();\n\n const asideRef = useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n setRef<HTMLDivElement>(ref, asideRef.current);\n }, [ref]);\n\n return (\n <React.Fragment>\n <div\n className={b(\n 'aside',\n {'menu-overflow-scroll': menuOverflow === 'scroll' && !compact},\n className,\n )}\n style={{width: size}}\n data-qa={qa}\n >\n <div className={b('aside-popup-anchor')} ref={asideRef} />\n {customBackground && (\n <div className={b('aside-custom-background', customBackgroundClassName)}>\n {customBackground}\n </div>\n )}\n\n <div className={b('aside-content', {['with-decoration']: headerDecoration})}>\n <Header />\n {aboveMenuContent}\n {visibleMenuItems?.length ? (\n <CompositeBar\n menuItemClassName={b('menu-item')}\n compositeId={MENU_ITEMS_COMPOSITE_ID}\n type=\"menu\"\n compact={compact}\n items={visibleMenuItems}\n menuGroups={menuGroups}\n menuMoreTitle={menuMoreTitle ?? i18n('label_more')}\n onItemClick={onItemClick}\n onMoreClick={onMenuMoreClick}\n menuOverflow={menuOverflow}\n collapsedMenuGroupIds={collapsedMenuGroupIds}\n defaultCollapsedMenuGroupIds={defaultCollapsedMenuGroupIds}\n onToggleMenuGroupCollapsed={onToggleMenuGroupCollapsed}\n />\n ) : (\n <div className={b('menu-items')} />\n )}\n <div className={b('footer')}>\n {renderFooter?.({\n size,\n compact: Boolean(compact),\n asideRef,\n })}\n </div>\n {!hideCollapseButton && <CollapseButton />}\n </div>\n </div>\n <Panels />\n </React.Fragment>\n );\n});\n\nFirstPanel.displayName = 'FirstPanel';\n"],"names":["useAsideHeaderInnerContext","useVisibleMenuItems","useRef","setRef","b","Header","CompositeBar","i18n","CollapseButton","Panels"],"mappings":"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"}
|
|
@@ -63,6 +63,7 @@ interface AsideHeaderGeneralProps extends QAProps {
|
|
|
63
63
|
onMenuMoreClick?: () => void;
|
|
64
64
|
onAllPagesClick?: () => void;
|
|
65
65
|
openModalSubscriber?: (subscriber: OpenModalSubscriber) => void;
|
|
66
|
+
aboveMenuContent?: React.ReactNode;
|
|
66
67
|
}
|
|
67
68
|
interface AsideHeaderDefaultProps {
|
|
68
69
|
panelItems?: PanelItemProps[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../../../src/components/AsideHeader/types.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {DrawerProps, PopupProps, QAProps} from '@gravity-ui/uikit';\n\nimport {RenderContentType} from '../Content';\nimport {LogoProps, MenuGroup, MenuItem, OpenModalSubscriber, TopAlertProps} from '../types';\n\nimport {AsideHeaderContextType} from './AsideHeaderContext';\n\nexport interface PanelItemProps extends DrawerProps {\n id: string;\n}\n\nexport interface LayoutProps {\n compact: boolean;\n className?: string;\n topAlert?: TopAlertProps;\n}\n\ninterface EditMenuProps {\n onOpenEditMode?: () => void;\n onToggleMenuItem?: (changedItem: AsideHeaderItem) => void;\n onResetSettingsToDefault?: () => void;\n enableSorting?: boolean;\n onChangeItemsOrder?: (changedItem: AsideHeaderItem, oldIndex: number, newIndex: number) => void;\n /**\n * Fired when visibility of a menu group is toggled from the All pages panel (pin on group header).\n * Use with `onMenuGroupsChanged` / controlled `menuGroups`.\n */\n onToggleMenuGroup?: (changedGroup: MenuGroup) => void;\n}\n\n/**\n * Menu overflow behavior.\n * - `collapse` — extra items collapse under a \"More\" popup (default).\n * - `scroll` — all items remain visible inside a scrollable container with a native thin scrollbar.\n *\n * In compact mode the menu always falls back to `collapse` regardless of this value\n * because a scrollbar over icon-only items is awkward.\n */\nexport type AsideHeaderMenuOverflow = 'collapse' | 'scroll';\n\ninterface AsideHeaderGeneralProps extends QAProps {\n logo?: LogoProps;\n className?: string;\n collapseTitle?: string;\n expandTitle?: string;\n menuMoreTitle?: string;\n /**\n * @see AsideHeaderMenuOverflow\n * @default 'collapse'\n */\n menuOverflow?: AsideHeaderMenuOverflow;\n topAlert?: TopAlertProps;\n customBackground?: React.ReactNode;\n customBackgroundClassName?: string;\n hideCollapseButton?: boolean;\n renderContent?: RenderContentType;\n renderFooter?: (data: {\n size: number;\n compact: boolean;\n asideRef: React.RefObject<HTMLDivElement>;\n }) => React.ReactNode;\n collapseButtonWrapper?: (\n defaultButton: React.ReactNode,\n data: {\n compact: boolean;\n onChangeCompact?: (compact: boolean) => void;\n },\n ) => React.ReactNode;\n editMenuProps?: EditMenuProps;\n onClosePanel?: () => void;\n onChangeCompact?: (compact: boolean) => void;\n onMenuMoreClick?: () => void;\n onAllPagesClick?: () => void;\n openModalSubscriber?: (subscriber: OpenModalSubscriber) => void;\n}\n\ninterface AsideHeaderDefaultProps {\n panelItems?: PanelItemProps[];\n subheaderItems?: AsideHeaderItem[];\n menuItems?: AsideHeaderItem[];\n menuGroups?: MenuGroup[];\n /**\n * Called only from **All pages** edit mode when the user toggles visibility of a **menu group** (group header pin), updating `menuGroup.hidden`.\n * Use with controlled `menuGroups`; not emitted for programmatic `menuGroups` changes outside All pages.\n */\n onMenuGroupsChanged?: (menuGroups: MenuGroup[]) => void;\n defaultMenuItems?: AsideHeaderItem[];\n onMenuItemsChanged?: (items: AsideHeaderItem[]) => void;\n headerDecoration?: boolean;\n /**\n * When provided, the map is the source of truth for which menu groups are collapsed\n * in inline (`menuOverflow: 'scroll'`) layout. Keys are `MenuGroup.id`, values mean collapsed.\n */\n collapsedMenuGroupIds?: Record<string, boolean>;\n /**\n * Initial collapsed state for groups when `collapsedMenuGroupIds` is not controlled.\n */\n defaultCollapsedMenuGroupIds?: Record<string, boolean>;\n /**\n * Called when the user toggles a group in inline layout. The parent should update\n * `collapsedMenuGroupIds` when using controlled mode.\n */\n onToggleMenuGroupCollapsed?: (groupId: string) => void;\n}\n\nexport type AsideHeaderInnerProps = AsideHeaderGeneralProps &\n AsideHeaderDefaultProps &\n AsideHeaderContextType;\n\nexport interface AsideHeaderProps\n extends AsideHeaderGeneralProps,\n LayoutProps,\n Partial<AsideHeaderDefaultProps> {}\n\nexport enum InnerPanels {\n AllPages = 'all-pages',\n}\n\n/** Menu item id for the All pages row (same value as {@link InnerPanels.AllPages}). */\nexport const ALL_PAGES_ID = InnerPanels.AllPages;\n\nexport interface AsideHeaderItem extends MenuItem {\n /**\n * @internal CompositeBar: group children rendered from the \"More\" overflow popover.\n */\n compositeBarMenuPopupItems?: AsideHeaderItem[];\n /**\n * @internal CompositeBar: optional heading in the overflow popover for a group row.\n */\n compositeBarMenuPopupTitle?: string;\n enableTooltip?: boolean;\n onItemClick?: (\n item: AsideHeaderItem,\n collapsed: boolean,\n event: React.MouseEvent<HTMLElement, MouseEvent>,\n ) => void;\n bringForward?: boolean;\n compact?: boolean;\n\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupVisible?: PopupProps['open'];\n /**\n * Floating element anchor ref object\n *\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupRef?: React.RefObject<HTMLElement>;\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupPlacement?: PopupProps['placement'];\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupOffset?: PopupProps['offset'];\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupKeepMounted?: PopupProps['keepMounted'];\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n renderPopupContent?: () => React.ReactNode;\n /**\n * This callback will be called when Escape key pressed on keyboard, or click outside was made\n * This behaviour could be disabled with `disableEscapeKeyDown`\n * and `disableOutsideClick` options\n *\n * @deprecated Use itemWrapper instead for popup functionality\n */\n onOpenChangePopup?: PopupProps['onOpenChange'];\n}\n"],"names":["InnerPanels"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../../../src/components/AsideHeader/types.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {DrawerProps, PopupProps, QAProps} from '@gravity-ui/uikit';\n\nimport {RenderContentType} from '../Content';\nimport {LogoProps, MenuGroup, MenuItem, OpenModalSubscriber, TopAlertProps} from '../types';\n\nimport {AsideHeaderContextType} from './AsideHeaderContext';\n\nexport interface PanelItemProps extends DrawerProps {\n id: string;\n}\n\nexport interface LayoutProps {\n compact: boolean;\n className?: string;\n topAlert?: TopAlertProps;\n}\n\ninterface EditMenuProps {\n onOpenEditMode?: () => void;\n onToggleMenuItem?: (changedItem: AsideHeaderItem) => void;\n onResetSettingsToDefault?: () => void;\n enableSorting?: boolean;\n onChangeItemsOrder?: (changedItem: AsideHeaderItem, oldIndex: number, newIndex: number) => void;\n /**\n * Fired when visibility of a menu group is toggled from the All pages panel (pin on group header).\n * Use with `onMenuGroupsChanged` / controlled `menuGroups`.\n */\n onToggleMenuGroup?: (changedGroup: MenuGroup) => void;\n}\n\n/**\n * Menu overflow behavior.\n * - `collapse` — extra items collapse under a \"More\" popup (default).\n * - `scroll` — all items remain visible inside a scrollable container with a native thin scrollbar.\n *\n * In compact mode the menu always falls back to `collapse` regardless of this value\n * because a scrollbar over icon-only items is awkward.\n */\nexport type AsideHeaderMenuOverflow = 'collapse' | 'scroll';\n\ninterface AsideHeaderGeneralProps extends QAProps {\n logo?: LogoProps;\n className?: string;\n collapseTitle?: string;\n expandTitle?: string;\n menuMoreTitle?: string;\n /**\n * @see AsideHeaderMenuOverflow\n * @default 'collapse'\n */\n menuOverflow?: AsideHeaderMenuOverflow;\n topAlert?: TopAlertProps;\n customBackground?: React.ReactNode;\n customBackgroundClassName?: string;\n hideCollapseButton?: boolean;\n renderContent?: RenderContentType;\n renderFooter?: (data: {\n size: number;\n compact: boolean;\n asideRef: React.RefObject<HTMLDivElement>;\n }) => React.ReactNode;\n collapseButtonWrapper?: (\n defaultButton: React.ReactNode,\n data: {\n compact: boolean;\n onChangeCompact?: (compact: boolean) => void;\n },\n ) => React.ReactNode;\n editMenuProps?: EditMenuProps;\n onClosePanel?: () => void;\n onChangeCompact?: (compact: boolean) => void;\n onMenuMoreClick?: () => void;\n onAllPagesClick?: () => void;\n openModalSubscriber?: (subscriber: OpenModalSubscriber) => void;\n aboveMenuContent?: React.ReactNode;\n}\n\ninterface AsideHeaderDefaultProps {\n panelItems?: PanelItemProps[];\n subheaderItems?: AsideHeaderItem[];\n menuItems?: AsideHeaderItem[];\n menuGroups?: MenuGroup[];\n /**\n * Called only from **All pages** edit mode when the user toggles visibility of a **menu group** (group header pin), updating `menuGroup.hidden`.\n * Use with controlled `menuGroups`; not emitted for programmatic `menuGroups` changes outside All pages.\n */\n onMenuGroupsChanged?: (menuGroups: MenuGroup[]) => void;\n defaultMenuItems?: AsideHeaderItem[];\n onMenuItemsChanged?: (items: AsideHeaderItem[]) => void;\n headerDecoration?: boolean;\n /**\n * When provided, the map is the source of truth for which menu groups are collapsed\n * in inline (`menuOverflow: 'scroll'`) layout. Keys are `MenuGroup.id`, values mean collapsed.\n */\n collapsedMenuGroupIds?: Record<string, boolean>;\n /**\n * Initial collapsed state for groups when `collapsedMenuGroupIds` is not controlled.\n */\n defaultCollapsedMenuGroupIds?: Record<string, boolean>;\n /**\n * Called when the user toggles a group in inline layout. The parent should update\n * `collapsedMenuGroupIds` when using controlled mode.\n */\n onToggleMenuGroupCollapsed?: (groupId: string) => void;\n}\n\nexport type AsideHeaderInnerProps = AsideHeaderGeneralProps &\n AsideHeaderDefaultProps &\n AsideHeaderContextType;\n\nexport interface AsideHeaderProps\n extends AsideHeaderGeneralProps,\n LayoutProps,\n Partial<AsideHeaderDefaultProps> {}\n\nexport enum InnerPanels {\n AllPages = 'all-pages',\n}\n\n/** Menu item id for the All pages row (same value as {@link InnerPanels.AllPages}). */\nexport const ALL_PAGES_ID = InnerPanels.AllPages;\n\nexport interface AsideHeaderItem extends MenuItem {\n /**\n * @internal CompositeBar: group children rendered from the \"More\" overflow popover.\n */\n compositeBarMenuPopupItems?: AsideHeaderItem[];\n /**\n * @internal CompositeBar: optional heading in the overflow popover for a group row.\n */\n compositeBarMenuPopupTitle?: string;\n enableTooltip?: boolean;\n onItemClick?: (\n item: AsideHeaderItem,\n collapsed: boolean,\n event: React.MouseEvent<HTMLElement, MouseEvent>,\n ) => void;\n bringForward?: boolean;\n compact?: boolean;\n\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupVisible?: PopupProps['open'];\n /**\n * Floating element anchor ref object\n *\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupRef?: React.RefObject<HTMLElement>;\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupPlacement?: PopupProps['placement'];\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupOffset?: PopupProps['offset'];\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n popupKeepMounted?: PopupProps['keepMounted'];\n /**\n * @deprecated Use itemWrapper instead for popup functionality\n */\n renderPopupContent?: () => React.ReactNode;\n /**\n * This callback will be called when Escape key pressed on keyboard, or click outside was made\n * This behaviour could be disabled with `disableEscapeKeyDown`\n * and `disableOutsideClick` options\n *\n * @deprecated Use itemWrapper instead for popup functionality\n */\n onOpenChangePopup?: PopupProps['onOpenChange'];\n}\n"],"names":["InnerPanels"],"mappings":";;AAqHYA;AAAZ,CAAA,UAAY,WAAW,EAAA;AACnB,IAAA,WAAA,CAAA,UAAA,CAAA,GAAA,WAAsB;AAC1B,CAAC,EAFWA,mBAAW,KAAXA,mBAAW,GAEtB,EAAA,CAAA,CAAA;AAED;AACa,MAAA,YAAY,GAAGA,mBAAW,CAAC;;;;"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @gravity-ui/navigation documentation
|
|
2
|
+
|
|
3
|
+
Documentation for the **installed** version of `@gravity-ui/navigation`.
|
|
4
|
+
Your training data may be outdated — these files are the source of truth.
|
|
5
|
+
|
|
6
|
+
Paths are relative to this file (`node_modules/@gravity-ui/navigation/build/docs/`).
|
|
7
|
+
|
|
8
|
+
## For AI agents
|
|
9
|
+
|
|
10
|
+
Application-shell navigation components for Gravity UI apps — the collapsible `AsideHeader` sidebar plus footers, drawers, logo, hotkeys and settings panels that frame a whole page.
|
|
11
|
+
|
|
12
|
+
### When to use
|
|
13
|
+
|
|
14
|
+
- The app's primary navigation frame: `AsideHeader` (collapsible side navigation) with `menuItems`, subheader, and footer sections.
|
|
15
|
+
- Supporting shell UI: `Drawer`/`DrawerItem`, `Footer`/`MobileFooter`, `MobileHeader`, `HotkeysPanel`, `Settings`, `ActionBar`, `Logo`.
|
|
16
|
+
- Laying out page content inside the navigation frame via `renderContent` / `PageLayout`.
|
|
17
|
+
|
|
18
|
+
### When not to use
|
|
19
|
+
|
|
20
|
+
- Generic in-page controls (buttons, tabs, menus, breadcrumbs) — use [`@gravity-ui/uikit`](https://github.com/gravity-ui/uikit); this package is the outer app chrome, not general components.
|
|
21
|
+
- Rendering the page body itself from config — use [`@gravity-ui/page-constructor`](https://github.com/gravity-ui/page-constructor).
|
|
22
|
+
- Client-side routing — this provides the navigation UI only; wire clicks to your own router.
|
|
23
|
+
|
|
24
|
+
### Common pitfalls
|
|
25
|
+
|
|
26
|
+
- **`AsideHeader` is controlled.** You must own the collapsed state with `compact` and update it in `onChangeCompact`; passing `compact` without the handler freezes the sidebar.
|
|
27
|
+
- **Menu items are `menuItems`, keyed by `id`.** Each item is `{id, title, icon, current, onItemClick}`; `icon` takes an icon component (e.g. from `@gravity-ui/icons`), not a string name.
|
|
28
|
+
- **Peer dependencies are required.** `@gravity-ui/uikit`, `@gravity-ui/icons`, and `@bem-react/classname` must be installed alongside `react`/`react-dom`.
|
|
29
|
+
- **Needs uikit setup.** Render inside `ThemeProvider` and import `@gravity-ui/uikit/styles/styles.css`, or the shell renders unstyled.
|
|
30
|
+
- **Page content goes through `renderContent`.** Render your routed content via the `renderContent` prop / `PageLayout`, not as `children`.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install @gravity-ui/navigation
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Ensure that peer dependencies are installed in your project
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm install --dev @gravity-ui/uikit@^7.2.0 @gravity-ui/icons@^2.2.0 @bem-react/classname@^1.6.0 react@^19.0.0 react-dom@^19.0.0
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
Render `AsideHeader` as the app shell. It is a controlled component — you own the collapsed state via `compact`/`onChangeCompact` — and your page content goes through `renderContent`. Set up `@gravity-ui/uikit` styles and `ThemeProvider` first (see the [uikit styles guide](https://github.com/gravity-ui/uikit?tab=readme-ov-file#styles)).
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import React from 'react';
|
|
50
|
+
import {AsideHeader} from '@gravity-ui/navigation';
|
|
51
|
+
import {Gear, House} from '@gravity-ui/icons';
|
|
52
|
+
import {ThemeProvider} from '@gravity-ui/uikit';
|
|
53
|
+
|
|
54
|
+
import '@gravity-ui/uikit/styles/styles.css';
|
|
55
|
+
|
|
56
|
+
export function App() {
|
|
57
|
+
const [compact, setCompact] = React.useState(false);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<ThemeProvider theme="light">
|
|
61
|
+
<AsideHeader
|
|
62
|
+
logo={{text: 'My App', href: '/'}}
|
|
63
|
+
compact={compact}
|
|
64
|
+
onChangeCompact={setCompact}
|
|
65
|
+
menuItems={[
|
|
66
|
+
{id: 'home', title: 'Home', icon: House, current: true},
|
|
67
|
+
{id: 'settings', title: 'Settings', icon: Gear},
|
|
68
|
+
]}
|
|
69
|
+
renderContent={() => <main>Page content</main>}
|
|
70
|
+
/>
|
|
71
|
+
</ThemeProvider>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Components
|
|
77
|
+
|
|
78
|
+
- [ActionBar](./components/ActionBar.md) — The component is a flexible horizontal bar that provides a standardized layout for arranging navigation elements, actions, and informational content within an application. It serves as a container for organizing UI elements like breadcrumbs, buttons, and dropdown menus into defined sections and groups.
|
|
79
|
+
- [AsideHeader](./components/AsideHeader.md) — AsideHeader is provided a flexible and customizable navigation experience within your application. Users can easily customize the appearance of the sidebar to match their branding colors also to add personalized links, icons that cater specifically to their application's functionality.
|
|
80
|
+
- [AsideHeader/components/AllPagesPanel](./components/AsideHeader/components/AllPagesPanel.md) — A navigation panel for managing and organizing application pages in the middle (menuItems) section of AsideHeader component. Panel provides drag-and-drop reordering, visibility toggles, pin/unpin and category grouping of menu items.
|
|
81
|
+
- [Footer](./components/Footer.md) — The page footer components. Use Footer for the desktop version and MobileFooter for the mobile version. Both components have the same properties.
|
|
82
|
+
- [HotkeysPanel](./components/HotkeysPanel.md) — A navigation panel for hotkeys documentation. The panel displays a set of hotkeys for your application with a description of their purpose.
|
|
83
|
+
- [Logo](./components/Logo.md) — Logo icon is wrapped in UIKit Button, text is wrapped in HTML tag a or div, when passing hasWrapper prop.
|
|
84
|
+
- [MobileHeader](./components/MobileHeader.md) — Header for Mobile navigation. MobileHeader provides maintaining Panels except for Modals.
|
|
85
|
+
- [Settings](./components/Settings.md) — The Settings component provides the layout for a settings panel with the following features.
|
|
86
|
+
|
|
87
|
+
## Hooks
|
|
88
|
+
|
|
89
|
+
- [useOverflowingHorizontalListItems](./hooks/useOverflowingHorizontalListItems.md) — A hook for determining which horizontal list items stay visible and which collapse into an overflow "more" dropdown.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# ActionBar
|
|
2
|
+
|
|
3
|
+
The component is a flexible horizontal bar that provides a standardized layout for arranging navigation elements, actions, and informational content within an application. It serves as a container for organizing UI elements like breadcrumbs, buttons, and dropdown menus into defined sections and groups.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```typescript jsx
|
|
8
|
+
import {Button} from '@gravity-ui/uikit';
|
|
9
|
+
import {Breadcrumbs as LegacyBreadcrumbs} from '@gravity-ui/uikit/legacy';
|
|
10
|
+
import {ActionBar} from '@gravity-ui/navigation';
|
|
11
|
+
|
|
12
|
+
function Page() {
|
|
13
|
+
return (
|
|
14
|
+
<ActionBar aria-label="Actions bar">
|
|
15
|
+
<ActionBar.Section>
|
|
16
|
+
<ActionBar.Group>
|
|
17
|
+
<ActionBar.Item>
|
|
18
|
+
<LegacyBreadcrumbs
|
|
19
|
+
lastDisplayedItemsCount={1}
|
|
20
|
+
firstDisplayedItemsCount={1}
|
|
21
|
+
items={[{text: 'Root Item', action() {}}]}
|
|
22
|
+
/>
|
|
23
|
+
</ActionBar.Item>
|
|
24
|
+
</ActionBar.Group>
|
|
25
|
+
|
|
26
|
+
<ActionBar.Group pull="right">
|
|
27
|
+
<ActionBar.Item>
|
|
28
|
+
<Button>Do something</Button>
|
|
29
|
+
</ActionBar.Item>
|
|
30
|
+
</ActionBar.Group>
|
|
31
|
+
</ActionBar.Section>
|
|
32
|
+
</ActionBar>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The `ActionBar` provides several nested components that work together to create a structured layout: `ActionBar.Section`, `ActionBar.Group`, `ActionBar.Item`, `ActionBar.Separator`.
|
|
38
|
+
|
|
39
|
+
## Properties
|
|
40
|
+
|
|
41
|
+
| Name | Description | Type | Default |
|
|
42
|
+
| :--------- | :----------------------------------------- | :-------------------: | :-----: |
|
|
43
|
+
| aria-label | HTML `aria-label` attribute | `string` | |
|
|
44
|
+
| className | HTML `class` attribute | `string` | |
|
|
45
|
+
| style | HTML `style` attribute | `React.CSSProperties` | |
|
|
46
|
+
| qa | `data-qa` HTML attribute, used for testing | `string` | |
|
|
47
|
+
|
|
48
|
+
## ActionBar.Section
|
|
49
|
+
|
|
50
|
+
Decorative component to visually separate different kinds of navigation.
|
|
51
|
+
There is two kinds of sections presented — `primary` and `secondary`. We recommend an app to have at least `primary`
|
|
52
|
+
section. `secondary` could be used for app specific controls, that should be accented with smaller paddings and
|
|
53
|
+
horizontal separator from `primary` section.
|
|
54
|
+
|
|
55
|
+
### Properties
|
|
56
|
+
|
|
57
|
+
| Name | Description | Type | Default |
|
|
58
|
+
| :-------- | :----------------------------------------------- | :------------------------: | :---------: |
|
|
59
|
+
| type | Type specifies the visual styling of the section | `"primary"`, `"secondary"` | `"primary"` |
|
|
60
|
+
| className | HTML `class` attribute | `string` | |
|
|
61
|
+
| style | HTML `style` attribute | `React.CSSProperties` | |
|
|
62
|
+
| qa | `data-qa` HTML attribute, used for testing | `string` | |
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import {Button} from '@gravity-ui/uikit';
|
|
66
|
+
import {Breadcrumbs as LegacyBreadcrumbs} from '@gravity-ui/uikit/legacy';
|
|
67
|
+
import {ActionBar} from '@gravity-ui/navigation';
|
|
68
|
+
|
|
69
|
+
<ActionBar aria-label="Actions bar">
|
|
70
|
+
<ActionBar.Section type="secondary">
|
|
71
|
+
<ActionBar.Group>
|
|
72
|
+
<ActionBar.Item>
|
|
73
|
+
<Button>Toggle Article TOC</Button>
|
|
74
|
+
</ActionBar.Item>
|
|
75
|
+
</ActionBar.Group>
|
|
76
|
+
</ActionBar.Section>
|
|
77
|
+
|
|
78
|
+
<ActionBar.Section type="primary">
|
|
79
|
+
<ActionBar.Group>
|
|
80
|
+
<ActionBar.Item>
|
|
81
|
+
<LegacyBreadcrumbs
|
|
82
|
+
lastDisplayedItemsCount={1}
|
|
83
|
+
firstDisplayedItemsCount={1}
|
|
84
|
+
items={[
|
|
85
|
+
{text: 'Wiki Main Page', action() {}},
|
|
86
|
+
{text: 'Wiki Article', action() {}},
|
|
87
|
+
]}
|
|
88
|
+
/>
|
|
89
|
+
</ActionBar.Item>
|
|
90
|
+
</ActionBar.Group>
|
|
91
|
+
</ActionBar.Section>
|
|
92
|
+
</ActionBar>;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## ActionBar.Group
|
|
96
|
+
|
|
97
|
+
Groups organize `ActionBar.Item` within a section and control their alignment.
|
|
98
|
+
|
|
99
|
+
### Properties
|
|
100
|
+
|
|
101
|
+
| Name | Description | Type | Default |
|
|
102
|
+
| :--------------- | :---------------------------------------------------------------- | :-----------------------------------------------------------------------------: | :-----: |
|
|
103
|
+
| pull | Controls the alignment of the group | `"left"`, `"left-grow"`, `"right"`, `"right-grow"`, `"center"`, `"center-grow"` | |
|
|
104
|
+
| stretchContainer | Set `flex-grow: 1` for Group. Need to support UIKit@7 Breadcrumbs | `boolean` | |
|
|
105
|
+
| className | HTML `class` attribute | `string` | |
|
|
106
|
+
| style | HTML `style` attribute | `React.CSSProperties` | |
|
|
107
|
+
| qa | `data-qa` HTML attribute, used for testing | `string` | |
|
|
108
|
+
|
|
109
|
+
## ActionBar.Item
|
|
110
|
+
|
|
111
|
+
Container for UI elements like buttons, breadcrumbs or other components must be in `ActionBar.Group`. The component adds margins between items.
|
|
112
|
+
|
|
113
|
+
### Properties
|
|
114
|
+
|
|
115
|
+
| Name | Description | Type | Default |
|
|
116
|
+
| :-------- | :----------------------------------------- | :-------------------: | :-----: |
|
|
117
|
+
| spacing | Enable spacing with previous item | `boolean` | `true` |
|
|
118
|
+
| className | HTML `class` attribute | `string` | |
|
|
119
|
+
| style | HTML `style` attribute | `React.CSSProperties` | |
|
|
120
|
+
| qa | `data-qa` HTML attribute, used for testing | `string` | |
|
|
121
|
+
|
|
122
|
+
## ActionBar.Separator
|
|
123
|
+
|
|
124
|
+
Visual divider that can be placed between items in a group to separate them visually.
|
|
125
|
+
|
|
126
|
+
### Example
|
|
127
|
+
|
|
128
|
+
```typescript jsx
|
|
129
|
+
import {Button} from '@gravity-ui/uikit';
|
|
130
|
+
import {Breadcrumbs as LegacyBreadcrumbs} from '@gravity-ui/uikit/legacy';
|
|
131
|
+
import {ActionBar} from '@gravity-ui/navigation';
|
|
132
|
+
|
|
133
|
+
function Page() {
|
|
134
|
+
return (
|
|
135
|
+
<ActionBar aria-label="Actions bar">
|
|
136
|
+
<ActionBar.Section>
|
|
137
|
+
<ActionBar.Group pull="right">
|
|
138
|
+
<ActionBar.Item>
|
|
139
|
+
<Button>Do something</Button>
|
|
140
|
+
</ActionBar.Item>
|
|
141
|
+
|
|
142
|
+
<ActionBar.Separator />
|
|
143
|
+
|
|
144
|
+
<ActionBar.Item>
|
|
145
|
+
<Button>Do something</Button>
|
|
146
|
+
</ActionBar.Item>
|
|
147
|
+
</ActionBar.Group>
|
|
148
|
+
</ActionBar.Section>
|
|
149
|
+
</ActionBar>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
```
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# AllPagesPanel
|
|
2
|
+
|
|
3
|
+
A navigation panel for managing and organizing application pages in the middle (menuItems) section of `AsideHeader` component. Panel provides drag-and-drop reordering, visibility toggles, pin/unpin and category grouping of menu items.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import {AsideHeader, type AsideHeaderProps} from '@gravity-ui/navigation';
|
|
10
|
+
|
|
11
|
+
const DEFAULT_MENU_ITEMS: AsideHeaderProps['menuItems'] = [
|
|
12
|
+
{item: {id: 'home', title: 'Home', icon: 'home'}},
|
|
13
|
+
{item: {id: 'analytics', title: 'Analytics', icon: 'chart'}},
|
|
14
|
+
{item: {id: 'settings', title: 'Settings', icon: 'gear'}},
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const Navigation: React.FC<React.PropsWithChildren> = ({children}) => {
|
|
18
|
+
const {defaultMenuItems, menuItems, setMenuItems} = useMenuItems();
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<AsideHeader
|
|
22
|
+
className={b()}
|
|
23
|
+
logo={{
|
|
24
|
+
icon: GravityLogo,
|
|
25
|
+
iconSize: 30,
|
|
26
|
+
text: 'Gravity App',
|
|
27
|
+
href: '#',
|
|
28
|
+
}}
|
|
29
|
+
menuItems={menuItems}
|
|
30
|
+
compact={compact}
|
|
31
|
+
onChangeCompact={setCompact}
|
|
32
|
+
renderContent={() => children}
|
|
33
|
+
// All pages
|
|
34
|
+
defaultMenuItems={defaultMenuItems}
|
|
35
|
+
editMenuProps={{enableSorting: true}}
|
|
36
|
+
onMenuItemsChanged={setMenuItems}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const useMenuItems = () => {
|
|
42
|
+
const location = useLocation();
|
|
43
|
+
|
|
44
|
+
const [menuItems, setMenuItems] = React.useState(DEFAULT_MENU_ITEMS);
|
|
45
|
+
|
|
46
|
+
const currentMenuItems = menuItems.map<AsideHeaderItem>((item, index) => {
|
|
47
|
+
if ('type' in item || index > 5) {
|
|
48
|
+
return item;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
...item,
|
|
53
|
+
current: (item.href || '') === location.pathname,
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return {defaultMenuItems: DEFAULT_MENU_ITEMS, menuItems: currentMenuItems, setMenuItems};
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Properties
|
|
62
|
+
|
|
63
|
+
| Name | Description | Type | Default |
|
|
64
|
+
| :----------------- | :----------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------: | :-----: |
|
|
65
|
+
| defaultMenuItems | Default items in the navigation middle section | [`Array<AsideHeaderItem>`](https://github.com/gravity-ui/navigation/blob/main/src/components/AsideHeader/README.md#menuitem) | `[]` |
|
|
66
|
+
| menuItems | Modifying items in the navigation middle section | [`Array<AsideHeaderItem>`](https://github.com/gravity-ui/navigation/blob/main/src/components/AsideHeader/README.md#menuitem) | `[]` |
|
|
67
|
+
| editMenuProps | desc | `type` | |
|
|
68
|
+
| onMenuItemsChanged | Callback will be called when updating list of the menuItems in `AllPagesPanel` | `(items: Array<AsideHeaderItem>) => void` | |
|
|
69
|
+
|
|
70
|
+
### `EditMenuProps`
|
|
71
|
+
|
|
72
|
+
Provides settings and callbacks for managing panel and menu items in the `AsideHeader`. Callbacks are optional, you can managing with `AsideHeader.onMenuItemsChanged` prop.
|
|
73
|
+
|
|
74
|
+
| Name | Description | Type | Default |
|
|
75
|
+
| :----------------------- | :------------------------------------------------------- | :---------------------------------------------------------------------------: | :-----: |
|
|
76
|
+
| enableSorting | Enable sorting functionality in the panel | `boolean` | |
|
|
77
|
+
| onOpenEditMode | Callback triggered when the edit mode is enabled | `() => void` | |
|
|
78
|
+
| onToggleMenuItem | Callback triggered when the menu item visible is toggled | `(changedItem: AsideHeaderItem) => void` | |
|
|
79
|
+
| onResetSettingsToDefault | Callback triggered when settings are reset to default | `() => void` | |
|
|
80
|
+
| onChangeItemsOrder | Callback triggered when the order of items is changed | `(changedItem: AsideHeaderItem, oldIndex: number, newIndex: number) => void;` | |
|