Merge pull request #30459 from backstage/canon-header-fixes

This commit is contained in:
Charles de Dreuille
2025-07-07 13:38:30 +01:00
committed by GitHub
8 changed files with 52 additions and 23 deletions
File diff suppressed because one or more lines are too long
+7 -8
View File
@@ -9482,13 +9482,7 @@
@media (width >= 640px) {
.canon-Container {
padding-inline: var(--canon-space-8);
}
}
@media (width >= 1024px) {
.canon-Container {
padding-inline: var(--canon-space-12);
padding-inline: var(--canon-space-5);
}
}
@@ -9568,6 +9562,7 @@
.canon-HeaderToolbar {
z-index: 10;
margin-bottom: var(--canon-space-6);
position: sticky;
top: 0;
@@ -9581,6 +9576,10 @@
left: 0;
right: 0;
}
&[data-has-tabs="true"] {
margin-bottom: 0;
}
}
.canon-HeaderToolbarWrapper {
@@ -9626,7 +9625,7 @@
}
.canon-HeaderToolbarControls {
right: var(--canon-space-2);
right: var(--canon-space-3);
position: absolute;
top: 50%;
transform: translateY(-50%);
@@ -7,12 +7,6 @@
@media (min-width: 640px) {
.canon-Container {
padding-inline: var(--canon-space-8);
}
}
@media (min-width: 1024px) {
.canon-Container {
padding-inline: var(--canon-space-12);
padding-inline: var(--canon-space-5);
}
}
@@ -185,3 +185,24 @@ export const WithLayoutAndHeaderPage: Story = {
</>
),
};
export const WithLayoutAndHeaderPageNoTabs: Story = {
args: {
menuItems,
breadcrumbs,
},
decorators: layoutDecorator,
parameters: {
layout: 'fullscreen',
},
render: args => (
<>
<Header {...args} />
<HeaderPage
title="Page title"
description="Page description"
options={args.menuItems}
/>
</>
),
};
@@ -18,6 +18,7 @@
position: sticky;
top: 0;
z-index: 10;
margin-bottom: var(--canon-space-6);
&::before {
content: '';
@@ -29,6 +30,10 @@
background-color: var(--canon-bg);
z-index: 0;
}
&[data-has-tabs='true'] {
margin-bottom: 0;
}
}
.canon-HeaderToolbarWrapper {
@@ -75,7 +80,7 @@
.canon-HeaderToolbarControls {
position: absolute;
right: var(--canon-space-2);
right: var(--canon-space-3);
top: 50%;
transform: translateY(-50%);
}
@@ -161,7 +166,6 @@
}
}
/* Active tab indicator */
.canon-HeaderTabActive {
content: '';
position: absolute;
@@ -175,7 +179,6 @@
opacity: 1;
}
/* Hovered tab indicator */
.canon-HeaderTabHovered {
content: '';
position: absolute;
@@ -26,6 +26,8 @@ import { HeaderTabs } from './HeaderTabs';
export const Header = (props: HeaderProps) => {
const { tabs, icon, title, menuItems, breadcrumbs, customActions } = props;
const hasTabs = tabs && tabs.length > 0;
return (
<>
<HeaderToolbar
@@ -34,6 +36,7 @@ export const Header = (props: HeaderProps) => {
menuItems={menuItems}
breadcrumbs={breadcrumbs}
customActions={customActions}
hasTabs={hasTabs}
/>
<HeaderTabs tabs={tabs} />
</>
@@ -18,7 +18,7 @@ import { Link } from 'react-aria-components';
import { useStyles } from '../../hooks/useStyles';
import { useRef, useState, useEffect } from 'react';
import { RiArrowRightSLine, RiMore2Line, RiShapesLine } from '@remixicon/react';
import type { HeaderProps } from './types';
import type { HeaderToolbarProps } from './types';
import { ButtonIcon } from '../ButtonIcon';
import { Menu } from '../Menu';
import { motion, useScroll, useTransform } from 'motion/react';
@@ -28,8 +28,8 @@ import { motion, useScroll, useTransform } from 'motion/react';
*
* @internal
*/
export const HeaderToolbar = (props: HeaderProps) => {
const { icon, title, menuItems, breadcrumbs, customActions } = props;
export const HeaderToolbar = (props: HeaderToolbarProps) => {
const { icon, title, menuItems, breadcrumbs, customActions, hasTabs } = props;
const { classNames } = useStyles('Header');
const { scrollY } = useScroll();
@@ -87,7 +87,7 @@ export const HeaderToolbar = (props: HeaderProps) => {
}, []);
return (
<div className={classNames.toolbar}>
<div className={classNames.toolbar} data-has-tabs={hasTabs}>
<div className={classNames.toolbarWrapper} ref={toolbarWrapperRef}>
<div className={classNames.toolbarContent} ref={toolbarContentRef}>
<div className={classNames.toolbarName}>
@@ -72,6 +72,15 @@ export interface HeaderTabProps {
setHoveredKey: (key: string | null) => void;
}
export interface HeaderToolbarProps {
icon?: HeaderProps['icon'];
title?: HeaderProps['title'];
breadcrumbs?: HeaderProps['breadcrumbs'];
customActions?: HeaderProps['customActions'];
menuItems?: HeaderProps['menuItems'];
hasTabs?: boolean;
}
export interface HeaderIndicatorsProps {
tabRefs: MutableRefObject<Map<string, HTMLDivElement>>;
tabsRef: MutableRefObject<HTMLDivElement | null>;