diff --git a/packages/canon/.storybook/themes/spotify.css b/packages/canon/.storybook/themes/spotify.css index 74c7138a21..8324de9d0e 100644 --- a/packages/canon/.storybook/themes/spotify.css +++ b/packages/canon/.storybook/themes/spotify.css @@ -119,11 +119,6 @@ padding-inline: var(--canon-space-3); } -.canon-MenuTrigger { - all: unset; - display: inline-flex; -} - .canon-MenuPopup { box-sizing: border-box; max-width: 21.25rem; diff --git a/packages/canon/css/styles.css b/packages/canon/css/styles.css index 9a5b19bff8..8f8677dd1b 100644 --- a/packages/canon/css/styles.css +++ b/packages/canon/css/styles.css @@ -9601,7 +9601,7 @@ } } -.canon-HeaderToolbarOptions { +.canon-HeaderToolbarControls { right: var(--canon-space-2); position: absolute; top: 50%; diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index 000a94f7dc..8b4d286074 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -513,7 +513,7 @@ export const componentDefinitions: { readonly toolbar: 'canon-HeaderToolbar'; readonly toolbarWrapper: 'canon-HeaderToolbarWrapper'; readonly toolbarContent: 'canon-HeaderToolbarContent'; - readonly toolbarOptions: 'canon-HeaderToolbarOptions'; + readonly toolbarControls: 'canon-HeaderToolbarControls'; readonly toolbarIcon: 'canon-HeaderToolbarIcon'; readonly toolbarName: 'canon-HeaderToolbarName'; readonly breadcrumbs: 'canon-HeaderBreadcrumbs'; @@ -995,9 +995,11 @@ export interface HeaderProps { // (undocumented) breadcrumbs?: HeaderBreadcrumb[]; // (undocumented) + customActions?: React.ReactNode; + // (undocumented) icon?: React.ReactNode; // (undocumented) - options?: HeaderOption[]; + menuItems?: HeaderOption[]; // (undocumented) tabs?: HeaderTab[]; // (undocumented) diff --git a/packages/canon/src/components/Header/Header.stories.tsx b/packages/canon/src/components/Header/Header.stories.tsx index 0554648bc9..4ff635fe5a 100644 --- a/packages/canon/src/components/Header/Header.stories.tsx +++ b/packages/canon/src/components/Header/Header.stories.tsx @@ -17,6 +17,7 @@ import type { Meta, StoryObj, StoryFn } from '@storybook/react'; import { Header } from './Header'; import { HeaderBreadcrumb, HeaderOption, HeaderTab } from './types'; +import { Button } from '../Button'; const meta = { title: 'Components/Header', @@ -59,7 +60,7 @@ const breadcrumbs: HeaderBreadcrumb[] = [ }, ]; -const options: HeaderOption[] = [ +const menuItems: HeaderOption[] = [ { label: 'Settings', value: 'settings', @@ -124,7 +125,13 @@ export const WithTabs: Story = { export const WithOptions: Story = { args: { - options, + menuItems, + }, +}; + +export const WithCustomActions: Story = { + args: { + customActions: , }, }; @@ -136,7 +143,7 @@ export const WithBreadcrumbs: Story = { export const WithAllComponents: Story = { args: { - options, + menuItems, tabs, breadcrumbs, }, @@ -144,7 +151,7 @@ export const WithAllComponents: Story = { export const WithLayout: Story = { args: { - options, + menuItems, tabs, breadcrumbs, }, diff --git a/packages/canon/src/components/Header/Header.styles.css b/packages/canon/src/components/Header/Header.styles.css index 76b7c6bcf4..ae0c753f2a 100644 --- a/packages/canon/src/components/Header/Header.styles.css +++ b/packages/canon/src/components/Header/Header.styles.css @@ -75,7 +75,7 @@ } } -.canon-HeaderToolbarOptions { +.canon-HeaderToolbarControls { position: absolute; right: var(--canon-space-2); top: 50%; diff --git a/packages/canon/src/components/Header/Header.tsx b/packages/canon/src/components/Header/Header.tsx index 9d7e65a6d1..913aedc80a 100644 --- a/packages/canon/src/components/Header/Header.tsx +++ b/packages/canon/src/components/Header/Header.tsx @@ -24,15 +24,16 @@ import { HeaderTabs } from './HeaderTabs'; * @public */ export const Header = (props: HeaderProps) => { - const { tabs, icon, title, options, breadcrumbs } = props; + const { tabs, icon, title, menuItems, breadcrumbs, customActions } = props; return ( <> diff --git a/packages/canon/src/components/Header/HeaderToolbar.tsx b/packages/canon/src/components/Header/HeaderToolbar.tsx index 95c01e1c88..8e84445b1c 100644 --- a/packages/canon/src/components/Header/HeaderToolbar.tsx +++ b/packages/canon/src/components/Header/HeaderToolbar.tsx @@ -17,7 +17,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 { RiArrowRightSLine, RiMore2Line } from '@remixicon/react'; import type { HeaderProps } from './types'; import { ButtonIcon } from '../ButtonIcon'; import { Menu } from '../Menu'; @@ -29,7 +29,7 @@ import { motion, useScroll, useTransform } from 'motion/react'; * @internal */ export const HeaderToolbar = (props: HeaderProps) => { - const { icon, title, options, breadcrumbs } = props; + const { icon, title, menuItems, breadcrumbs, customActions } = props; const { classNames } = useStyles('Header'); const { scrollY } = useScroll(); @@ -38,7 +38,7 @@ export const HeaderToolbar = (props: HeaderProps) => { // Refs for collision detection const toolbarWrapperRef = useRef(null); const toolbarContentRef = useRef(null); - const toolbarOptionsRef = useRef(null); + const toolbarControlsRef = useRef(null); // State for breadcrumb visibility const [showBreadcrumbs, setShowBreadcrumbs] = useState(true); @@ -51,7 +51,7 @@ export const HeaderToolbar = (props: HeaderProps) => { const resizeObserver = new ResizeObserver(() => { const wrapper = toolbarWrapperRef.current; const content = toolbarContentRef.current; - const options = toolbarOptionsRef.current; + const options = toolbarControlsRef.current; if (!wrapper || !content) return; @@ -91,9 +91,7 @@ export const HeaderToolbar = (props: HeaderProps) => {
-
- {icon || } -
+ {icon &&
{icon}
} {title || 'Your plugin'}
{breadcrumbs && ( @@ -128,23 +126,24 @@ export const HeaderToolbar = (props: HeaderProps) => { )}
-
- {options && ( +
+ {customActions} + {menuItems && ( ( } variant="secondary" + {...props} /> )} /> - {options.map(option => ( + {menuItems.map(option => ( option.onClick?.()} diff --git a/packages/canon/src/components/Header/types.ts b/packages/canon/src/components/Header/types.ts index 6cdd51b7d6..efecf52e4d 100644 --- a/packages/canon/src/components/Header/types.ts +++ b/packages/canon/src/components/Header/types.ts @@ -24,9 +24,10 @@ import { MutableRefObject } from 'react'; export interface HeaderProps { icon?: React.ReactNode; title?: string; - tabs?: HeaderTab[]; - options?: HeaderOption[]; breadcrumbs?: HeaderBreadcrumb[]; + customActions?: React.ReactNode; + menuItems?: HeaderOption[]; + tabs?: HeaderTab[]; } /** diff --git a/packages/canon/src/utils/componentDefinitions.ts b/packages/canon/src/utils/componentDefinitions.ts index 29f6ecb7d1..3dcb19f138 100644 --- a/packages/canon/src/utils/componentDefinitions.ts +++ b/packages/canon/src/utils/componentDefinitions.ts @@ -240,7 +240,7 @@ export const componentDefinitions = { toolbar: 'canon-HeaderToolbar', toolbarWrapper: 'canon-HeaderToolbarWrapper', toolbarContent: 'canon-HeaderToolbarContent', - toolbarOptions: 'canon-HeaderToolbarOptions', + toolbarControls: 'canon-HeaderToolbarControls', toolbarIcon: 'canon-HeaderToolbarIcon', toolbarName: 'canon-HeaderToolbarName', breadcrumbs: 'canon-HeaderBreadcrumbs',