SingleTopNav: Flip collapse arrows for better alignment (#94081)

flip megamenu arrows for better alignment
This commit is contained in:
Ashley Harrison 2024-10-02 11:08:34 +01:00 committed by GitHub
parent ddbbf8df4b
commit cf61ab3da2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 18 deletions

View File

@ -23,7 +23,7 @@ export function MegaMenuHeader({ handleMegaMenu, handleDockedMenu, onClose }: Pr
return (
<div className={styles.header}>
<Stack alignItems="center" minWidth={0}>
<Stack alignItems="center" minWidth={0} gap={0.25}>
<ToolbarButton narrow onClick={handleMegaMenu}>
<Branding.MenuLogo className={styles.img} />
</ToolbarButton>
@ -69,7 +69,7 @@ const getStyles = (theme: GrafanaTheme2) => ({
display: 'flex',
gap: theme.spacing(1),
justifyContent: 'space-between',
padding: theme.spacing(0, 1, 0, 0.5),
padding: theme.spacing(0, 1, 0, 0.75),
height: TOP_BAR_LEVEL_HEIGHT,
minHeight: TOP_BAR_LEVEL_HEIGHT,
}),

View File

@ -5,6 +5,7 @@ import { useLocation } from 'react-router-dom-v5-compat';
import { useLocalStorage } from 'react-use';
import { GrafanaTheme2, NavModelItem, toIconName } from '@grafana/data';
import { config } from '@grafana/runtime';
import { useStyles2, Text, IconButton, Icon, Stack } from '@grafana/ui';
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 item = useRef<HTMLLIElement>(null);
const isSingleTopNav = config.featureToggles.singleTopNav;
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 (
<li ref={item} className={styles.listItem}>
<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 === MAX_DEPTH && <div className={styles.itemConnector} />}
<div className={styles.collapseButtonWrapper}>
{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>
{!isSingleTopNav && collapseIcon}
<div className={styles.collapsibleSectionWrapper}>
<MegaMenuItemText
isActive={isActive}
@ -118,6 +132,7 @@ export function MegaMenuItem({ link, activeItem, level = 0, onClick, onPin, isPi
</div>
</MegaMenuItemText>
</div>
{isSingleTopNav && collapseIcon}
</div>
{showExpandButton && sectionExpanded && (
<ul className={styles.children}>

View File

@ -1,8 +1,9 @@
import { css } from '@emotion/css';
import { useEffect, useState } from 'react';
import { SelectableValue } from '@grafana/data';
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
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 { contextSrv } from 'app/core/services/context_srv';
import { getUserOrganizations, setUserOrganization } from 'app/features/org/state/actions';
@ -17,6 +18,7 @@ export function OrganizationSwitcher() {
const theme = useTheme2();
const dispatch = useDispatch();
const orgs = useSelector((state) => state.organization.userOrgs);
const styles = useStyles2(getStyles);
const onSelectChange = (option: SelectableValue<UserOrg>) => {
if (option.value) {
setUserOrganization(option.value.orgId);
@ -46,7 +48,11 @@ export function OrganizationSwitcher() {
if (orgs?.length <= 1) {
if (config.featureToggles.singleTopNav) {
return <Text truncate>{Branding.AppTitle}</Text>;
return (
<span className={styles.brandTitle}>
<Text truncate>{Branding.AppTitle}</Text>
</span>
);
} else {
return null;
}
@ -56,3 +62,9 @@ export function OrganizationSwitcher() {
return <Switcher orgs={orgs} onSelectChange={onSelectChange} />;
}
const getStyles = (theme: GrafanaTheme2) => ({
brandTitle: css({
paddingLeft: theme.spacing(1),
}),
});

View File

@ -96,7 +96,7 @@ const getStyles = (theme: GrafanaTheme2, menuDockedAndOpen: boolean) => ({
gap: theme.spacing(1),
alignItems: 'center',
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}`,
justifyContent: 'space-between',