Skip to content

Commit

Permalink
Add a menu title for floating menu (#319)
Browse files Browse the repository at this point in the history
* feat: extract menu title from FloatingMenu

* feat: use `MenuTitle` in `FloatingMenu`

* feat: add `MenuTitle` to `Menu` story
  • Loading branch information
florianduros authored Feb 21, 2025
1 parent 98dccbf commit bece139
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 19 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 2 additions & 5 deletions src/components/Menu/FloatingMenu.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ Please see LICENSE files in the repository root for full details.
}

.title {
color: var(--cpd-color-text-secondary);
padding-inline: var(--cpd-space-4x);
padding-block-end: calc(var(--cpd-space-2x) - var(--cpd-border-width-1));
border-block-end: var(--cpd-border-width-1) solid var(--cpd-color-gray-400);
margin-block: 0 var(--cpd-space-2x);
/** Override MenuTitle margin top **/
margin-block-start: 0 !important;
}
17 changes: 4 additions & 13 deletions src/components/Menu/FloatingMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,7 @@ import React, {
useId,
} from "react";
import styles from "./FloatingMenu.module.css";
import { Text } from "../Typography/Text";

interface TitleProps {
title: string;
id: string;
}

const MenuTitle: React.FC<TitleProps> = ({ title, id }) => (
<Text as="h3" id={id} className={styles.title} size="sm" weight="semibold">
{title}
</Text>
);
import { MenuTitle } from "./MenuTitle.tsx";

interface Props extends ComponentPropsWithoutRef<"div"> {
/**
Expand Down Expand Up @@ -62,7 +51,9 @@ export const FloatingMenu = forwardRef<HTMLDivElement, Props>(
className={classnames(className, styles.menu)}
{...props}
>
{showTitle && <MenuTitle title={title} id={titleId} />}
{showTitle && (
<MenuTitle className={styles.title} title={title} id={titleId} />
)}
{children}
</div>
);
Expand Down
7 changes: 7 additions & 0 deletions src/components/Menu/Menu.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Menu as MenuComponent } from "./Menu";
import { MenuItem } from "./MenuItem";
import { Separator } from "../Separator/Separator";
import { Button } from "../Button/Button";
import { MenuTitle } from "./MenuTitle.tsx";

type Props = Omit<
React.ComponentProps<typeof MenuComponent>,
Expand All @@ -39,6 +40,12 @@ const Template: React.FC<Props> = (args) => {
label="Notifications"
onSelect={() => {}}
/>
<MenuTitle title="Other section" />
<MenuItem
Icon={NotificationsIcon}
label="Other Notifications"
onSelect={() => {}}
/>
<MenuItem Icon={ChatProblemIcon} label="Feedback" onSelect={() => {}} />
<Separator />
<MenuItem
Expand Down
14 changes: 14 additions & 0 deletions src/components/Menu/MenuTitle.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright 2025 New Vector Ltd
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/

.menu-title {
color: var(--cpd-color-text-secondary);
padding-inline: var(--cpd-space-4x);
padding-block-end: calc(var(--cpd-space-2x) - var(--cpd-border-width-1));
border-block-end: var(--cpd-border-width-1) solid var(--cpd-color-gray-400);
margin-block: var(--cpd-space-2x);
}
29 changes: 29 additions & 0 deletions src/components/Menu/MenuTitle.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2025 New Vector Ltd
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/

import { MenuTitle as MenuTitleComponent } from "./MenuTitle";
import { Meta, StoryFn } from "@storybook/react";
import React, { ComponentProps } from "react";

export default {
title: "Menu/MenuTitle",
component: MenuTitleComponent,
tags: ["autodocs"],
argTypes: {},
args: {
title: "Title",
},
} as Meta<typeof MenuTitleComponent>;

const Template: StoryFn<typeof MenuTitleComponent> = (
args: ComponentProps<typeof MenuTitleComponent>,
) => {
return <MenuTitleComponent {...args} />;
};

export const Default = Template.bind({});
Default.args = {};
18 changes: 18 additions & 0 deletions src/components/Menu/MenuTitle.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright 2025 New Vector Ltd
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/

import { describe, expect, it } from "vitest";
import { render } from "@testing-library/react";
import { MenuTitle } from "./MenuTitle.tsx";
import React from "react";

describe("MenuTitle", () => {
it("renders", () => {
const { asFragment } = render(<MenuTitle title="Title" />);
expect(asFragment()).toMatchSnapshot();
});
});
40 changes: 40 additions & 0 deletions src/components/Menu/MenuTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2025 New Vector Ltd
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/

import React from "react";
import { Text } from "../Typography/Text.tsx";
import styles from "./MenuTitle.module.css";
import classnames from "classnames";

interface MenuTitleProps {
/**
* The title of the menu.
*/
title: string;
/**
* The id of the menu title.
*/
id?: string;
/**
* The CSS class.
*/
className?: string;
}

export const MenuTitle: React.FC<MenuTitleProps> = ({
title,
id,
className,
}) => {
const classes = classnames(styles["menu-title"], className);

return (
<Text as="h3" id={id} className={classes} size="sm" weight="semibold">
{title}
</Text>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ exports[`FloatingMenu > renders 1`] = `
role="menu"
>
<h3
class="_typography_489030 _font-body-sm-semibold_489030 _title_3295a1"
class="_typography_489030 _font-body-sm-semibold_489030 _menu-title_7bbc38 _title_3295a1"
id=":r0:"
>
Settings
Expand Down
11 changes: 11 additions & 0 deletions src/components/Menu/__snapshots__/MenuTitle.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`MenuTitle > renders 1`] = `
<DocumentFragment>
<h3
class="_typography_489030 _font-body-sm-semibold_489030 _menu-title_7bbc38"
>
Title
</h3>
</DocumentFragment>
`;

0 comments on commit bece139

Please sign in to comment.