mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
SingleTopNav: Flip collapse arrows for better alignment (#94081)
flip megamenu arrows for better alignment
This commit is contained in:
parent
ddbbf8df4b
commit
cf61ab3da2
@ -23,7 +23,7 @@ export function MegaMenuHeader({ handleMegaMenu, handleDockedMenu, onClose }: Pr
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
<Stack alignItems="center" minWidth={0}>
|
<Stack alignItems="center" minWidth={0} gap={0.25}>
|
||||||
<ToolbarButton narrow onClick={handleMegaMenu}>
|
<ToolbarButton narrow onClick={handleMegaMenu}>
|
||||||
<Branding.MenuLogo className={styles.img} />
|
<Branding.MenuLogo className={styles.img} />
|
||||||
</ToolbarButton>
|
</ToolbarButton>
|
||||||
@ -69,7 +69,7 @@ const getStyles = (theme: GrafanaTheme2) => ({
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
gap: theme.spacing(1),
|
gap: theme.spacing(1),
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
padding: theme.spacing(0, 1, 0, 0.5),
|
padding: theme.spacing(0, 1, 0, 0.75),
|
||||||
height: TOP_BAR_LEVEL_HEIGHT,
|
height: TOP_BAR_LEVEL_HEIGHT,
|
||||||
minHeight: TOP_BAR_LEVEL_HEIGHT,
|
minHeight: TOP_BAR_LEVEL_HEIGHT,
|
||||||
}),
|
}),
|
||||||
|
@ -5,6 +5,7 @@ import { useLocation } from 'react-router-dom-v5-compat';
|
|||||||
import { useLocalStorage } from 'react-use';
|
import { useLocalStorage } from 'react-use';
|
||||||
|
|
||||||
import { GrafanaTheme2, NavModelItem, toIconName } from '@grafana/data';
|
import { GrafanaTheme2, NavModelItem, toIconName } from '@grafana/data';
|
||||||
|
import { config } from '@grafana/runtime';
|
||||||
import { useStyles2, Text, IconButton, Icon, Stack } from '@grafana/ui';
|
import { useStyles2, Text, IconButton, Icon, Stack } from '@grafana/ui';
|
||||||
import { useGrafana } from 'app/core/context/GrafanaContext';
|
import { useGrafana } from 'app/core/context/GrafanaContext';
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick, onPin, isPi
|
|||||||
);
|
);
|
||||||
const showExpandButton = level < MAX_DEPTH && Boolean(linkHasChildren(link) || link.emptyMessage);
|
const showExpandButton = level < MAX_DEPTH && Boolean(linkHasChildren(link) || link.emptyMessage);
|
||||||
const item = useRef<HTMLLIElement>(null);
|
const item = useRef<HTMLLIElement>(null);
|
||||||
|
const isSingleTopNav = config.featureToggles.singleTopNav;
|
||||||
|
|
||||||
const styles = useStyles2(getStyles);
|
const styles = useStyles2(getStyles);
|
||||||
|
|
||||||
@ -74,6 +76,29 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick, onPin, isPi
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getIconName(isExpanded: boolean) {
|
||||||
|
if (isSingleTopNav) {
|
||||||
|
return isExpanded ? 'angle-up' : 'angle-down';
|
||||||
|
} else {
|
||||||
|
return isExpanded ? 'angle-down' : 'angle-right';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const collapseIcon = (
|
||||||
|
<div className={styles.collapseButtonWrapper}>
|
||||||
|
{showExpandButton && (
|
||||||
|
<IconButton
|
||||||
|
aria-label={`${sectionExpanded ? 'Collapse' : 'Expand'} section ${link.text}`}
|
||||||
|
className={styles.collapseButton}
|
||||||
|
onClick={() => setSectionExpanded(!sectionExpanded)}
|
||||||
|
name={getIconName(Boolean(sectionExpanded))}
|
||||||
|
size="md"
|
||||||
|
variant="secondary"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li ref={item} className={styles.listItem}>
|
<li ref={item} className={styles.listItem}>
|
||||||
<div
|
<div
|
||||||
@ -83,18 +108,7 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick, onPin, isPi
|
|||||||
>
|
>
|
||||||
{level !== 0 && <Indent level={level === MAX_DEPTH ? level - 1 : level} spacing={3} />}
|
{level !== 0 && <Indent level={level === MAX_DEPTH ? level - 1 : level} spacing={3} />}
|
||||||
{level === MAX_DEPTH && <div className={styles.itemConnector} />}
|
{level === MAX_DEPTH && <div className={styles.itemConnector} />}
|
||||||
<div className={styles.collapseButtonWrapper}>
|
{!isSingleTopNav && collapseIcon}
|
||||||
{showExpandButton && (
|
|
||||||
<IconButton
|
|
||||||
aria-label={`${sectionExpanded ? 'Collapse' : 'Expand'} section ${link.text}`}
|
|
||||||
className={styles.collapseButton}
|
|
||||||
onClick={() => setSectionExpanded(!sectionExpanded)}
|
|
||||||
name={sectionExpanded ? 'angle-down' : 'angle-right'}
|
|
||||||
size="md"
|
|
||||||
variant="secondary"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className={styles.collapsibleSectionWrapper}>
|
<div className={styles.collapsibleSectionWrapper}>
|
||||||
<MegaMenuItemText
|
<MegaMenuItemText
|
||||||
isActive={isActive}
|
isActive={isActive}
|
||||||
@ -118,6 +132,7 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick, onPin, isPi
|
|||||||
</div>
|
</div>
|
||||||
</MegaMenuItemText>
|
</MegaMenuItemText>
|
||||||
</div>
|
</div>
|
||||||
|
{isSingleTopNav && collapseIcon}
|
||||||
</div>
|
</div>
|
||||||
{showExpandButton && sectionExpanded && (
|
{showExpandButton && sectionExpanded && (
|
||||||
<ul className={styles.children}>
|
<ul className={styles.children}>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
|
import { css } from '@emotion/css';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { SelectableValue } from '@grafana/data';
|
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||||
import { config, locationService } from '@grafana/runtime';
|
import { config, locationService } from '@grafana/runtime';
|
||||||
import { Text, useTheme2 } from '@grafana/ui';
|
import { Text, useStyles2, useTheme2 } from '@grafana/ui';
|
||||||
import { useMediaQueryChange } from 'app/core/hooks/useMediaQueryChange';
|
import { useMediaQueryChange } from 'app/core/hooks/useMediaQueryChange';
|
||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
import { getUserOrganizations, setUserOrganization } from 'app/features/org/state/actions';
|
import { getUserOrganizations, setUserOrganization } from 'app/features/org/state/actions';
|
||||||
@ -17,6 +18,7 @@ export function OrganizationSwitcher() {
|
|||||||
const theme = useTheme2();
|
const theme = useTheme2();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const orgs = useSelector((state) => state.organization.userOrgs);
|
const orgs = useSelector((state) => state.organization.userOrgs);
|
||||||
|
const styles = useStyles2(getStyles);
|
||||||
const onSelectChange = (option: SelectableValue<UserOrg>) => {
|
const onSelectChange = (option: SelectableValue<UserOrg>) => {
|
||||||
if (option.value) {
|
if (option.value) {
|
||||||
setUserOrganization(option.value.orgId);
|
setUserOrganization(option.value.orgId);
|
||||||
@ -46,7 +48,11 @@ export function OrganizationSwitcher() {
|
|||||||
|
|
||||||
if (orgs?.length <= 1) {
|
if (orgs?.length <= 1) {
|
||||||
if (config.featureToggles.singleTopNav) {
|
if (config.featureToggles.singleTopNav) {
|
||||||
return <Text truncate>{Branding.AppTitle}</Text>;
|
return (
|
||||||
|
<span className={styles.brandTitle}>
|
||||||
|
<Text truncate>{Branding.AppTitle}</Text>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -56,3 +62,9 @@ export function OrganizationSwitcher() {
|
|||||||
|
|
||||||
return <Switcher orgs={orgs} onSelectChange={onSelectChange} />;
|
return <Switcher orgs={orgs} onSelectChange={onSelectChange} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getStyles = (theme: GrafanaTheme2) => ({
|
||||||
|
brandTitle: css({
|
||||||
|
paddingLeft: theme.spacing(1),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
@ -96,7 +96,7 @@ const getStyles = (theme: GrafanaTheme2, menuDockedAndOpen: boolean) => ({
|
|||||||
gap: theme.spacing(1),
|
gap: theme.spacing(1),
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
padding: theme.spacing(0, 1),
|
padding: theme.spacing(0, 1),
|
||||||
paddingLeft: menuDockedAndOpen ? theme.spacing(3.5) : theme.spacing(0.5),
|
paddingLeft: menuDockedAndOpen ? theme.spacing(3.5) : theme.spacing(0.75),
|
||||||
borderBottom: `1px solid ${theme.colors.border.weak}`,
|
borderBottom: `1px solid ${theme.colors.border.weak}`,
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user