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 (
|
||||
<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,
|
||||
}),
|
||||
|
@ -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}>
|
||||
|
@ -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),
|
||||
}),
|
||||
});
|
||||
|
@ -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',
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user