diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/index.ts b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/index.ts index 7570b0ec4613d..245345464d436 100644 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/index.ts +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/index.ts @@ -16,3 +16,5 @@ export type { Props as RecentlyAccessedProps } from './recently_accessed'; export { FeedbackBtn } from './feedback_btn'; export type { PanelContent, PanelComponentProps } from './panel'; + +export { NavigationSectionUI } from './navigation_section'; diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_item_open_panel.tsx b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_item_open_panel.tsx deleted file mode 100644 index 78d4808c04a64..0000000000000 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_item_open_panel.tsx +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the "Elastic License - * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side - * Public License v 1"; you may not use this file except in compliance with, at - * your election, the "Elastic License 2.0", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import React, { useCallback, type FC } from 'react'; -import classNames from 'classnames'; -import { css } from '@emotion/react'; -import { transparentize, EuiButton } from '@elastic/eui'; -import type { ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; -import { SubItemTitle } from './subitem_title'; -import { isActiveFromUrl } from '../../utils'; -import type { NavigateToUrlFn } from '../../types'; -import { usePanel } from './panel'; - -interface Props { - item: ChromeProjectNavigationNode; - navigateToUrl: NavigateToUrlFn; - activeNodes: ChromeProjectNavigationNode[][]; -} - -export const NavigationItemOpenPanel: FC = ({ item, activeNodes }: Props) => { - const { open: openPanel, close: closePanel, selectedNode } = usePanel(); - const { title, deepLink, withBadge } = item; - const { id, path } = item; - const isExpanded = selectedNode?.path === path; - const isActive = isActiveFromUrl(item.path, activeNodes) || isExpanded; - - const dataTestSubj = classNames(`nav-item`, `nav-item-${path}`, { - [`nav-item-deepLinkId-${deepLink?.id}`]: !!deepLink, - [`nav-item-id-${id}`]: id, - [`nav-item-isActive`]: isActive, - }); - - const togglePanel = useCallback( - (target: EventTarget) => { - if (selectedNode?.id === item.id) { - closePanel(); - } else { - openPanel(item, target as Element); - } - }, - [selectedNode?.id, item, closePanel, openPanel] - ); - - const onLinkClick = useCallback( - (e: React.MouseEvent) => { - e.preventDefault(); - togglePanel(e.target); - }, - [togglePanel] - ); - - return ( - css` - background-color: ${isActive - ? transparentize(euiTheme.colors.lightShade, 0.5) - : 'transparent'}; - transform: none !important; /* don't translateY 1px */ - color: inherit; - font-weight: inherit; - padding-inline: ${euiTheme.size.s}; - & > span { - justify-content: flex-start; - position: relative; - } - ${!withBadge - ? ` - & .euiIcon { - position: absolute; - right: 0; - top: 0; - transform: translateY(50%); - } - ` - : ` - & .euiBetaBadge { - margin-left: -${euiTheme.size.m}; - } - `} - `} - data-test-subj={dataTestSubj} - > - {withBadge ? : title} - - ); -}; diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/index.ts b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/index.ts new file mode 100644 index 0000000000000..3049f97b95f84 --- /dev/null +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export { NavigationSectionUI } from './navigation_section_ui'; diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/navigation_item_open_panel.tsx b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/navigation_item_open_panel.tsx new file mode 100644 index 0000000000000..cd130c0a22c0f --- /dev/null +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/navigation_item_open_panel.tsx @@ -0,0 +1,125 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +import { Theme, css } from '@emotion/react'; +import classNames from 'classnames'; +import React, { useCallback, type FC } from 'react'; + +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; +import type { ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; +import type { NavigateToUrlFn } from '../../../types'; +import { isActiveFromUrl } from '../../../utils'; +import { usePanel } from '../panel'; +import { SubItemBadge } from '../subitem_badge'; + +interface Props { + item: ChromeProjectNavigationNode; + navigateToUrl: NavigateToUrlFn; + activeNodes: ChromeProjectNavigationNode[][]; +} + +const panelOpenerStyles = { + button: ({ euiTheme }: Theme) => + css` + color: inherit; + font-weight: inherit; + transform: none !important; /* don't translateY 1px */ + padding-inline: calc(${euiTheme.size.xs} * 2); + background-color: inherit; + + &:hover { + background-color: ${euiTheme.colors.backgroundBaseInteractiveHover}; + } + + &.isSelected { + background-color: ${euiTheme.colors.backgroundLightPrimary}; + &:hover { + background-color: ${euiTheme.colors.backgroundLightPrimary}; + } + } + + &.isExpanded { + background-color: ${euiTheme.colors.backgroundBaseInteractiveHover}; + } + + /* get the spacing of panel opener's title and icons to match the spacing from other nav subitems */ + .panelIcon { + margin-left: -${euiTheme.size.xxs}; + } + .hasIcon { + padding-left: calc(${euiTheme.size.xxs} / 2); + } + `, + flexGroup: ({ euiTheme }: Theme) => css` + gap: calc(${euiTheme.size.s} / 1.5); + `, +}; + +export const NavigationItemOpenPanel: FC = ({ item, activeNodes }: Props) => { + const { open: openPanel, close: closePanel, selectedNode } = usePanel(); + const { title, deepLink, icon, withBadge, badgeOptions } = item; + const { id, path } = item; + const isExpanded = selectedNode?.path === path; + const isSelected = isActiveFromUrl(item.path, activeNodes); + + const dataTestSubj = classNames(`nav-item`, `nav-item-${path}`, { + [`nav-item-deepLinkId-${deepLink?.id}`]: !!deepLink, + [`nav-item-id-${id}`]: id, + [`nav-item-isActive`]: isSelected || isExpanded, + }); + + const togglePanel = useCallback( + (target: EventTarget) => { + if (selectedNode?.id === item.id) { + closePanel(); + } else { + openPanel(item, target as Element); + } + }, + [selectedNode?.id, item, closePanel, openPanel] + ); + + const onLinkClick = useCallback( + (e: React.MouseEvent) => { + e.preventDefault(); + togglePanel(e.target); + }, + [togglePanel] + ); + + return ( + + + {icon && ( + + + + )} + + {title} + + {withBadge && ( + + + + )} + + + ); +}; diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/navigation_section_ui.tsx similarity index 86% rename from src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx rename to src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/navigation_section_ui.tsx index 03d46b611213c..e2fe6fc3c6d5e 100644 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section_ui.tsx +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/navigation_section/navigation_section_ui.tsx @@ -8,34 +8,71 @@ */ import React, { type FC, useMemo, useEffect, useState, useCallback } from 'react'; -import { css } from '@emotion/react'; +import { Theme, css } from '@emotion/react'; import { EuiTitle, EuiCollapsibleNavItem, EuiSpacer, type EuiCollapsibleNavItemProps, type EuiCollapsibleNavSubItemProps, + useEuiTheme, } from '@elastic/eui'; import type { ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; import classnames from 'classnames'; import type { EuiThemeSize, RenderAs } from '@kbn/core-chrome-browser/src/project_navigation'; -import { SubItemTitle } from './subitem_title'; -import { useNavigation as useServices } from '../../services'; -import { isAbsoluteLink, isActiveFromUrl, isAccordionNode } from '../../utils'; -import type { BasePathService, NavigateToUrlFn } from '../../types'; -import { useNavigation } from '../navigation'; -import { EventTracker } from '../../analytics'; -import { useAccordionState } from '../hooks'; +import { SubItemTitle } from '../subitem_title'; +import { useNavigation as useServices } from '../../../services'; +import { isAbsoluteLink, isActiveFromUrl, isAccordionNode } from '../../../utils'; +import type { BasePathService, NavigateToUrlFn } from '../../../types'; +import { useNavigation } from '../../navigation'; +import { EventTracker } from '../../../analytics'; +import { useAccordionState } from '../../hooks'; import { DEFAULT_IS_COLLAPSIBLE, DEFAULT_RENDER_AS, DEFAULT_SPACE_BETWEEN_LEVEL_1_GROUPS, -} from '../constants'; -import type { EuiCollapsibleNavSubItemPropsEnhanced } from '../types'; -import { PanelContext, usePanel } from './panel'; +} from '../../constants'; +import type { EuiCollapsibleNavSubItemPropsEnhanced } from '../../types'; +import { PanelContext, usePanel } from '../panel'; import { NavigationItemOpenPanel } from './navigation_item_open_panel'; +const sectionStyles = { + blockTitle: ({ euiTheme }: Theme) => ({ + paddingBlock: euiTheme.size.xs, + paddingInline: euiTheme.size.s, + }), + euiCollapsibleNavItem: ({ euiTheme }: Theme) => css` + .euiAccordion__childWrapper { + transition: none; // Remove the transition as it does not play well with dynamic links added to the accordion + } + .euiAccordion__children .euiCollapsibleNavItem__items { + padding-inline-start: ${euiTheme.size.m}; + margin-inline-start: ${euiTheme.size.m}; + } + &:only-child .euiCollapsibleNavItem__icon { + transform: scale(1.33); + } + `, + euiCollapsibleNavSubItem: ({ euiTheme }: Theme) => css` + &.euiLink, + &.euiCollapsibleNavLink { + :hover { + background-color: ${euiTheme.colors.backgroundBaseInteractiveHover}; + } + &.isSelected { + :hover { + background-color: ${euiTheme.colors.backgroundLightPrimary}; + } + } + } + + .euiAccordion__childWrapper { + background-color: ${euiTheme.colors.backgroundBasePlain}; + } + `, +}; + const nodeHasLink = (navNode: ChromeProjectNavigationNode) => Boolean(navNode.deepLink) || Boolean(navNode.href); @@ -151,26 +188,21 @@ const isEuiCollapsibleNavItemProps = ( return true; }; -const renderBlockTitle: ( - navNode: ChromeProjectNavigationNode -) => Required['renderItem'] = (navNode) => () => { +const BlockTitle: React.FC<{ navNode: ChromeProjectNavigationNode }> = ({ navNode }) => { + const { euiTheme } = useEuiTheme(); const { title, spaceBefore } = navNode; const dataTestSubj = getTestSubj(navNode); return ( - { - return { - marginTop: spaceBefore ? euiTheme.size[spaceBefore] : undefined, - paddingBlock: euiTheme.size.xs, - paddingInline: euiTheme.size.s, - }; - }} - > -
{title}
-
+
+ +
{title}
+
+
); }; @@ -183,7 +215,7 @@ const renderGroup = ( if (!!navGroup.title) { itemPrepend = { - renderItem: renderBlockTitle(navGroup), + renderItem: () => , }; } else if (spaceBefore) { itemPrepend = { @@ -423,12 +455,13 @@ function nodeToEuiCollapsibleNavProps( } // Render as a link or an accordion - const items: Array = [ + const items: EuiCollapsibleNavSubItemPropsEnhanced[] = [ { id, path, isSelected, onClick, + css: sectionStyles.euiCollapsibleNavSubItem, icon: navNode.icon, // @ts-expect-error title accepts JSX elements and they render correctly but the type definition expects a string title: navNode.withBadge ? : navNode.title, @@ -461,6 +494,7 @@ interface Props { } export const NavigationSectionUI: FC = React.memo(({ navNode: _navNode }) => { + const { euiTheme } = useEuiTheme(); const { activeNodes } = useNavigation(); const { navigateToUrl, eventTracker, basePath, isSideNavCollapsed } = useServices(); const [items, setItems] = useState(); @@ -563,25 +597,25 @@ export const NavigationSectionUI: FC = React.memo(({ navNode: _navNode }) return null; } - const navItemStyles = css` - .euiAccordion__childWrapper { - transition: none; // Remove the transition as it does not play well with dynamic links added to the accordion - } - `; - - if (!items) { - return ; - } - // Item type ExclusiveUnion - accordions should not contain links const { href, linkProps, ...rest } = props; return ( - +
+ {items ? ( + + ) : ( + + )} +
); }); diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/context.tsx b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/context.tsx index 08d9819319dfe..6f0bd995691d4 100644 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/context.tsx +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/context.tsx @@ -17,7 +17,7 @@ import React, { useEffect, useRef, } from 'react'; -import type { ChromeProjectNavigationNode, PanelSelectedNode } from '@kbn/core-chrome-browser'; +import type { PanelSelectedNode } from '@kbn/core-chrome-browser'; import { DefaultContent } from './default_content'; @@ -26,9 +26,9 @@ export interface PanelContext { toggle: () => void; open: (navNode: PanelSelectedNode, openerEl: Element | null) => void; close: () => void; - /** The selected node is the node in the main panel that opens the Panel */ + /** The expanded node is the node in the main panel that opens the Panel */ selectedNode: PanelSelectedNode | null; - /** Reference to the selected nav node element in the DOM */ + /** Reference to the expanded nav node element in the DOM */ selectedNodeEl: React.MutableRefObject; /** Handler to retrieve the component to render in the panel */ getContent: () => React.ReactNode; @@ -37,7 +37,6 @@ export interface PanelContext { const Context = React.createContext(null); interface Props { - activeNodes: ChromeProjectNavigationNode[][]; selectedNode?: PanelSelectedNode | null; setSelectedNode?: (node: PanelSelectedNode | null) => void; } @@ -45,10 +44,10 @@ interface Props { export const PanelProvider: FC> = ({ children, selectedNode: selectedNodeProp = null, - setSelectedNode, + setSelectedNode: setSelectedNodeProp, }) => { const [isOpen, setIsOpen] = useState(false); - const [selectedNode, setActiveNode] = useState(selectedNodeProp); + const [selectedNode, setSelectedNode] = useState(selectedNodeProp); const selectedNodeEl = useRef(null); const toggle = useCallback(() => { @@ -57,7 +56,7 @@ export const PanelProvider: FC> = ({ const open = useCallback( (navNode: PanelSelectedNode, openerEl: Element | null) => { - setActiveNode(navNode); + setSelectedNode(navNode); const navNodeEl = openerEl?.closest(`[data-test-subj~=nav-item]`); if (navNodeEl) { @@ -65,22 +64,22 @@ export const PanelProvider: FC> = ({ } setIsOpen(true); - setSelectedNode?.(navNode); + setSelectedNodeProp?.(navNode); }, - [setSelectedNode] + [setSelectedNodeProp] ); const close = useCallback(() => { - setActiveNode(null); + setSelectedNode(null); selectedNodeEl.current = null; setIsOpen(false); - setSelectedNode?.(null); - }, [setSelectedNode]); + setSelectedNodeProp?.(null); + }, [setSelectedNodeProp]); useEffect(() => { if (selectedNodeProp === undefined) return; - setActiveNode(selectedNodeProp); + setSelectedNode(selectedNodeProp); if (selectedNodeProp) { setIsOpen(true); diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/default_content.tsx b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/default_content.tsx index 01393b1ec18b8..98384c8db2cfc 100644 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/default_content.tsx +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/default_content.tsx @@ -75,29 +75,23 @@ export const DefaultContent: FC = ({ selectedNode }) => { {/* Panel navigation */} - - <> - {serializedChildren && ( - <> - {serializedChildren.map((child, i) => { - const hasHorizontalRuleBefore = - i === 0 ? false : !!serializedChildren?.[i - 1]?.appendHorizontalRule; - const isGroup = !!child.children; - return isGroup ? ( - - - - ) : ( - - ); - })} - - )} - + + {serializedChildren?.map((child, i) => { + const hasHorizontalRuleBefore = + i === 0 ? false : !!serializedChildren?.[i - 1]?.appendHorizontalRule; + const isGroup = !!child.children; + return isGroup ? ( + + + + ) : ( + + ); + }) ?? null} ); diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/panel_nav_item.tsx b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/panel_nav_item.tsx index 324b52ea7f29f..c6b26fba5e4e8 100644 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/panel_nav_item.tsx +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/panel_nav_item.tsx @@ -9,10 +9,10 @@ import React, { FC, useCallback } from 'react'; import type { ChromeProjectNavigationNode } from '@kbn/core-chrome-browser'; -import { EuiListGroupItem, transparentize, useEuiTheme } from '@elastic/eui'; -import classNames from 'classnames'; -import { css } from '@emotion/css'; +import { EuiListGroupItem } from '@elastic/eui'; +import { Theme, css } from '@emotion/react'; +import { useNavigation } from '../../navigation'; import { useNavigation as useServices } from '../../../services'; import { SubItemTitle } from '../subitem_title'; import { usePanel } from './context'; @@ -21,13 +21,37 @@ interface Props { item: ChromeProjectNavigationNode; } +const panelNavStyles = ({ euiTheme }: Theme) => css` + background-color: ${euiTheme.colors.backgroundBaseSubdued}; + &:focus-within { + background-color: ${euiTheme.colors.backgroundBaseSubdued}; + } + &:hover { + background-color: ${euiTheme.colors.backgroundBaseInteractiveHover}; + } + + &.isSelected { + background-color: ${euiTheme.colors.backgroundLightPrimary}; + &:focus-within { + background-color: ${euiTheme.colors.backgroundLightPrimary}; + } + &:hover { + background-color: ${euiTheme.colors.backgroundLightPrimary}; + } + } + + & svg[class*='EuiExternalLinkIcon'] { + margin-left: auto; + } +`; + export const PanelNavItem: FC = ({ item }) => { const { navigateToUrl } = useServices(); + const { activeNodes } = useNavigation(); const { close: closePanel } = usePanel(); const { id, icon, deepLink, openInNewTab, isExternalLink, renderItem } = item; const href = deepLink?.url ?? item.href; - const { euiTheme } = useEuiTheme(); const onClick = useCallback( (e) => { @@ -40,25 +64,22 @@ export const PanelNavItem: FC = ({ item }) => { [closePanel, href, navigateToUrl] ); - return renderItem ? ( - renderItem() - ) : ( + if (renderItem) { + return renderItem(); + } + + const isSelected = activeNodes[0]?.find(({ path: activePath }) => { + return activePath === item.path; + }); + + return ( } wrapText - className={classNames( - 'sideNavPanelLink', - css` - &.sideNavPanelLink:hover { - background-color: ${transparentize(euiTheme.colors.lightShade, 0.5)}; - } - & svg[class*='EuiExternalLinkIcon'] { - margin-left: auto; - } - ` - )} size="s" + css={panelNavStyles} + className={isSelected ? 'isSelected' : undefined} data-test-subj={`panelNavItem panelNavItem-id-${item.id}`} href={href} iconType={icon} diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/styles.ts b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/styles.ts index 1d40eaeba7d49..8a9de42a4b7b9 100644 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/styles.ts +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/components/panel/styles.ts @@ -7,7 +7,7 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { transparentize, type EuiThemeComputed } from '@elastic/eui'; +import { type EuiThemeComputed } from '@elastic/eui'; import { css } from '@emotion/css'; const PANEL_WIDTH = '270px'; @@ -26,22 +26,7 @@ export const getPanelWrapperStyles = () => css` `; export const getNavPanelStyles = (euiTheme: EuiThemeComputed<{}>) => css` - background-color: ${euiTheme.colors.body}; + background-color: ${euiTheme.colors.backgroundBaseSubdued}; height: 100%; width: ${PANEL_WIDTH}; - - .sideNavPanelLink { - &:focus-within { - background-color: transparent; - a { - text-decoration: auto; - } - } - &:hover { - background-color: ${transparentize(euiTheme.colors.primary, 0.1)}; - a { - text-decoration: underline; - } - } - } `; diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/navigation.stories.tsx b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/navigation.stories.tsx index 92ad3d3d8cdb4..29aec5e21552e 100644 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/navigation.stories.tsx +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/navigation.stories.tsx @@ -577,6 +577,15 @@ generalLayoutNavTree.footer = correctPaths( export const GeneralLayoutStructure = (args: NavigationServices) => { const services = storybookMock.getServices(args); + services.activeNodes$ = of([ + [ + { id: '', path: 'example_project' }, + { id: '', path: 'example_project.root-section1' }, + { id: '', path: 'example_project.root-section1.item03' }, + { id: '', path: 'example_project.root-section1.item03.child-section4' }, + { id: '', path: 'example_project.root-section1.item03.child-section4.sub3' }, + ], + ]); return ( diff --git a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/navigation.tsx b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/navigation.tsx index 84d0107d8d16a..e84f5f541e9e8 100644 --- a/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/navigation.tsx +++ b/src/platform/packages/shared/shared-ux/chrome/navigation/src/ui/navigation.tsx @@ -7,19 +7,24 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import React, { createContext, FC, useCallback, useContext, useMemo } from 'react'; -import useObservable from 'react-use/lib/useObservable'; +import { EuiCollapsibleNavBeta, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import type { ChromeProjectNavigationNode, - RootNavigationItemDefinition, - RecentlyAccessedDefinition, NavigationTreeDefinitionUI, + RecentlyAccessedDefinition, + RootNavigationItemDefinition, } from '@kbn/core-chrome-browser'; +import React, { createContext, FC, useCallback, useContext, useMemo } from 'react'; +import useObservable from 'react-use/lib/useObservable'; import type { Observable } from 'rxjs'; -import { EuiCollapsibleNavBeta, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; -import { RecentlyAccessed, NavigationPanel, PanelProvider, FeedbackBtn } from './components'; import { useNavigation as useNavigationService } from '../services'; -import { NavigationSectionUI } from './components/navigation_section_ui'; +import { + FeedbackBtn, + NavigationPanel, + NavigationSectionUI, + PanelProvider, + RecentlyAccessed, +} from './components'; const isRecentlyAccessedDefinition = ( item: ChromeProjectNavigationNode | RecentlyAccessedDefinition @@ -76,11 +81,7 @@ const NavigationComp: FC = ({ navigationTree$, dataTestSubj }) => { ); return ( - + {/* Main navigation content */}