This is an automated email from the ASF dual-hosted git repository.

sadpandajoe pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 7382ee0bfec fix(dashboard): prevent header metadata bar from 
overlapping action buttons at narrow widths (#43845)
7382ee0bfec is described below

commit 7382ee0bfecbf31da1e13d459066335fd425f017
Author: Joe Li <[email protected]>
AuthorDate: Tue Sep 8 09:34:09 2026 -0700

    fix(dashboard): prevent header metadata bar from overlapping action buttons 
at narrow widths (#43845)
    
    Co-authored-by: Claude Sonnet 5 <[email protected]>
---
 .../PageHeaderWithActions.stories.tsx              | 102 +++++++++++++++++++++
 .../PageHeaderWithActions.test.tsx                 |  19 +++-
 .../src/components/PageHeaderWithActions/index.tsx |   6 +-
 3 files changed, 125 insertions(+), 2 deletions(-)

diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/PageHeaderWithActions.stories.tsx
 
b/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/PageHeaderWithActions.stories.tsx
new file mode 100644
index 00000000000..50d84268257
--- /dev/null
+++ 
b/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/PageHeaderWithActions.stories.tsx
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import { Icons } from '../Icons';
+import { Button } from '../Button';
+import MetadataBar, { MetadataType } from '../MetadataBar';
+import { Menu } from '../Menu';
+import { PageHeaderWithActions, PageHeaderWithActionsProps } from '.';
+
+export default {
+  title: 'Design System/Components/PageHeaderWithActions',
+  component: PageHeaderWithActions,
+  parameters: {
+    layout: 'fullscreen',
+    docs: {
+      description: {
+        component:
+          'Header used on entity pages (e.g. the dashboard page) combining an 
editable title with badges, a metadata bar, and page-level actions.',
+      },
+    },
+  },
+};
+
+// Mirrors src/dashboard/components/Header's real composition: an editable
+// title, the certified badge, and a titlePanelAdditionalItems cluster of a
+// refresh button, an auto-refresh indicator, a published-status toggle, and
+// a MetadataBar (Last Modified + Editor) -- the same items the real
+// dashboard header packs into that space -- so this story reproduces the
+// header's real narrow-viewport layout behavior, not just the isolated
+// MetadataBar. The real RefreshButton/AutoRefreshIndicator/PublishedStatus
+// components live in src/dashboard and depend on this package, so they
+// can't be imported here without inverting that dependency; these are
+// same-sized stand-ins built from core components instead.
+export const DashboardHeader = (args: PageHeaderWithActionsProps) => (
+  <PageHeaderWithActions {...args} />
+);
+
+DashboardHeader.args = {
+  editableTitleProps: {
+    title: 'Q3 Executive Revenue and Growth Overview Dashboard',
+    placeholder: 'Add the name of the dashboard',
+    onSave: () => {},
+    canEdit: true,
+    label: 'Dashboard title',
+  },
+  showTitlePanelItems: true,
+  certificatiedBadgeProps: {
+    certifiedBy: 'Jane Doe',
+    details: 'Certified by the BI team',
+  },
+  showFaveStar: true,
+  faveStarProps: { itemId: 1, saveFaveStar: () => {}, isStarred: false },
+  titlePanelAdditionalItems: [
+    <Button key="refresh-button" buttonStyle="link" tooltip="Refresh 
dashboard">
+      <Icons.ReloadOutlined iconSize="l" />
+    </Button>,
+    <Icons.SyncOutlined key="auto-refresh-indicator" iconSize="l" />,
+    <Button key="published-status" buttonStyle="link">
+      Published
+    </Button>,
+    <MetadataBar
+      key="metadata-bar"
+      tooltipPlacement="bottom"
+      items={[
+        {
+          type: MetadataType.LastModified,
+          value: '2 hours ago',
+          modifiedBy: 'Jane Doe',
+        },
+        {
+          type: MetadataType.Editor,
+          createdBy: 'Jane Doe',
+          editors: ['Jane Doe', 'John Smith'],
+          createdOn: 'a week ago',
+        },
+      ]}
+    />,
+  ],
+  rightPanelAdditionalItems: <button type="button">Edit dashboard</button>,
+  additionalActionsMenu: (
+    <Menu
+      items={[{ label: 'Edit properties', key: '1' }]}
+      data-test="additional-actions-menu"
+    />
+  ),
+  menuDropdownProps: {},
+};
diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/PageHeaderWithActions.test.tsx
 
b/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/PageHeaderWithActions.test.tsx
index 2a3d17c9a55..0f90c99a675 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/PageHeaderWithActions.test.tsx
+++ 
b/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/PageHeaderWithActions.test.tsx
@@ -18,7 +18,12 @@
  */
 
 import { render, screen, userEvent } from '@superset-ui/core/spec';
-import { PageHeaderWithActions, PageHeaderWithActionsProps } from './index';
+import { supersetTheme } from '@apache-superset/core/theme';
+import {
+  buttonsStyles,
+  PageHeaderWithActions,
+  PageHeaderWithActionsProps,
+} from './index';
 import { Menu } from '../Menu';
 
 const defaultProps: PageHeaderWithActionsProps = {
@@ -54,3 +59,15 @@ test('Renders', async () => {
   await userEvent.click(screen.getByLabelText('Menu actions trigger'));
   expect(defaultProps.menuDropdownProps.onOpenChange).toHaveBeenCalled();
 });
+
+test('clips the title panel buttons/metadata cluster instead of letting it 
overflow into the actions menu', () => {
+  // jsdom doesn't compute real flexbox layout, so it can't verify the
+  // overlap itself is fixed; this guards the underlying CSS from
+  // regressing instead. Without `overflow: hidden`, this wrapper's
+  // automatic flex minimum size is based on its content rather than 0, so
+  // it refuses to shrink -- forcing the title to absorb all the space
+  // pressure until the cluster's content renders outside its box and
+  // overlaps the actions menu once the title has fully collapsed.
+  const { styles } = buttonsStyles(supersetTheme);
+  expect(styles).toMatch(/overflow:\s*hidden/);
+});
diff --git 
a/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/index.tsx
 
b/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/index.tsx
index cd1ef78f834..7b25c8c858d 100644
--- 
a/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/index.tsx
+++ 
b/superset-frontend/packages/superset-ui-core/src/components/PageHeaderWithActions/index.tsx
@@ -99,9 +99,13 @@ const headerStyles = (theme: SupersetTheme) => css`
   }
 `;
 
-const buttonsStyles = (theme: SupersetTheme) => css`
+// Exported only so PageHeaderWithActions.test.tsx can assert on the
+// `overflow: hidden` declaration directly; not part of the component's
+// public API.
+export const buttonsStyles = (theme: SupersetTheme) => css`
   display: flex;
   align-items: center;
+  overflow: hidden;
   padding-left: ${theme.sizeUnit * 2}px;
 
   & .anticon-star {

Reply via email to