From cce5a21933880d1803d205f433de89dcc304faac Mon Sep 17 00:00:00 2001 From: Jake Howell Date: Tue, 4 Aug 2026 13:22:52 +1000 Subject: [PATCH] chore(site): remove unused SelectMenu component (#27800) `SelectMenu` was only referenced by its Storybook story. Nothing in the app consumed it. Delete the component and story so we drop the unused MUI `MenuItem` / `MenuList` wrapper and avoid treating dead demui code as a shared primitive. --- site/src/components/Popover/Popover.tsx | 2 - .../SelectMenu/SelectMenu.stories.tsx | 133 ---------------- site/src/components/SelectMenu/SelectMenu.tsx | 149 ------------------ 3 files changed, 284 deletions(-) delete mode 100644 site/src/components/SelectMenu/SelectMenu.stories.tsx delete mode 100644 site/src/components/SelectMenu/SelectMenu.tsx diff --git a/site/src/components/Popover/Popover.tsx b/site/src/components/Popover/Popover.tsx index 4827b01015..9121730169 100644 --- a/site/src/components/Popover/Popover.tsx +++ b/site/src/components/Popover/Popover.tsx @@ -11,8 +11,6 @@ export type PopoverContentProps = React.ComponentPropsWithRef< disablePortal?: boolean; }; -export type PopoverTriggerProps = PopoverPrimitive.PopoverTriggerProps; - export const Popover = PopoverPrimitive.Root; export const PopoverTrigger = PopoverPrimitive.Trigger; diff --git a/site/src/components/SelectMenu/SelectMenu.stories.tsx b/site/src/components/SelectMenu/SelectMenu.stories.tsx deleted file mode 100644 index c9c5bfb4c1..0000000000 --- a/site/src/components/SelectMenu/SelectMenu.stories.tsx +++ /dev/null @@ -1,133 +0,0 @@ -import type { Meta, StoryObj } from "@storybook/react-vite"; -import { action } from "storybook/actions"; -import { userEvent, within } from "storybook/test"; -import { Avatar } from "#/components/Avatar/Avatar"; -import { withDesktopViewport } from "#/testHelpers/storybook"; -import { - SelectMenu, - SelectMenuButton, - SelectMenuContent, - SelectMenuIcon, - SelectMenuItem, - SelectMenuList, - SelectMenuSearch, - SelectMenuTrigger, -} from "./SelectMenu"; - -const meta: Meta = { - title: "components/SelectMenu", - component: SelectMenu, - render: function SelectMenuRender() { - const opts = options(50); - const selectedOpt = opts[20]; - - return ( - - - } - > - {selectedOpt} - - - - {}} /> - - {opts.map((o) => ( - - - - - {o} - - ))} - - - - ); - }, - decorators: [withDesktopViewport], -}; - -function options(n: number): string[] { - return Array.from({ length: n }, (_, i) => `Item ${i + 1}`); -} - -export default meta; -type Story = StoryObj; - -export const Closed: Story = {}; - -export const Open: Story = { - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - const button = canvas.getByRole("button"); - await userEvent.click(button); - }, -}; - -export const LongButtonText: Story = { - render: function SelectMenuRender() { - const longOption = "Very long text that should be truncated"; - const opts = [...options(50), longOption]; - const selectedOpt = longOption; - - return ( - - - } - > - {selectedOpt} - - - - {}} /> - - {opts.map((o) => ( - - - - - {o} - - ))} - - - - ); - }, -}; - -export const NoSelectedOption: Story = { - render: function SelectMenuRender() { - const opts = options(50); - - return ( - - - All users - - - - - {opts.map((o) => ( - - - - - {o} - - ))} - - - - ); - }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); - const button = canvas.getByRole("button"); - await userEvent.click(button); - }, -}; diff --git a/site/src/components/SelectMenu/SelectMenu.tsx b/site/src/components/SelectMenu/SelectMenu.tsx deleted file mode 100644 index 78b2bf2659..0000000000 --- a/site/src/components/SelectMenu/SelectMenu.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import MenuItem, { type MenuItemProps } from "@mui/material/MenuItem"; -import MenuList, { type MenuListProps } from "@mui/material/MenuList"; -import { CheckIcon } from "lucide-react"; -import { - Children, - type FC, - type HTMLProps, - isValidElement, - type ReactElement, - useMemo, -} from "react"; -import { ChevronDownIcon } from "#/components/AnimatedIcons/ChevronDown"; -import { Button, type ButtonProps } from "#/components/Button/Button"; -import { - Popover, - PopoverContent, - type PopoverContentProps, - PopoverTrigger, - type PopoverTriggerProps, -} from "#/components/Popover/Popover"; -import { - SearchField, - type SearchFieldProps, -} from "#/components/SearchField/SearchField"; -import { cn } from "#/utils/cn"; - -export const SelectMenu = Popover; - -export const SelectMenuTrigger: FC = (props) => { - return ; -}; - -export const SelectMenuContent: FC = (props) => { - return ( - - ); -}; - -type SelectMenuButtonProps = ButtonProps & { - startIcon?: React.ReactNode; -}; - -export const SelectMenuButton: React.FC = ({ - className, - startIcon, - children, - ...props -}) => { - return ( - - ); -}; - -export const SelectMenuSearch: FC = ({ - className, - ...props -}) => { - return ( - - ); -}; - -export const SelectMenuList: FC = ({ - children, - className, - ...attrs -}) => { - const items = useMemo(() => { - let items = Children.toArray(children); - if (!items.every(isValidElement)) { - throw new Error("SelectMenuList only accepts MenuItem children"); - } - items = moveSelectedElementToFirst(items as ReactElement[]); - return items; - }, [children]); - - return ( - - {items} - - ); -}; - -function moveSelectedElementToFirst(items: ReactElement[]) { - const selectedElement = items.find((i) => i.props.selected); - if (!selectedElement) { - return items; - } - const selectedElementIndex = items.indexOf(selectedElement); - const newItems = items.slice(); - newItems.splice(selectedElementIndex, 1); - newItems.unshift(selectedElement); - return newItems; -} - -export const SelectMenuIcon: FC> = ({ - children, - className, - ...attrs -}) => { - return ( -
- {children} -
- ); -}; - -export const SelectMenuItem: FC = ({ - children, - className, - selected, - ...attrs -}) => { - return ( - - {children} - {selected && } - - ); -};