diff --git a/web/src/components/ui/button-with-dropdown.tsx b/web/src/components/ui/button-with-dropdown.tsx new file mode 100644 index 0000000000000..2b98f325a46db --- /dev/null +++ b/web/src/components/ui/button-with-dropdown.tsx @@ -0,0 +1,43 @@ +import * as React from "react"; +import { Button, type VariantProps } from "./button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, + type DropdownMenuContentProps, +} from "./dropdown-menu"; + +interface ButtonWithDropdownProps extends VariantProps { + children: React.ReactNode; + menuContent: React.ReactNode; + dropdownContentProps?: Omit; + className?: string; +} + +const ButtonWithDropdown = React.forwardRef( + ({ children, menuContent, variant, size, dropdownContentProps, className, ...props }, ref) => { + return ( + + + + + + {menuContent} + + + ); + } +); + +ButtonWithDropdown.displayName = "ButtonWithDropdown"; + +export { ButtonWithDropdown }; \ No newline at end of file diff --git a/web/src/components/ui/button.tsx b/web/src/components/ui/button.tsx index 13fc5d8257478..6c7543b23fe40 100644 --- a/web/src/components/ui/button.tsx +++ b/web/src/components/ui/button.tsx @@ -34,11 +34,19 @@ const Button = React.forwardRef< React.ComponentProps<"button"> & VariantProps & { asChild?: boolean; + hasIconDivider?: boolean; } ->(({ className, variant, size, asChild = false, ...props }, ref) => { +>(({ className, variant, size, asChild = false, hasIconDivider = false, ...props }, ref) => { const Comp = asChild ? Slot : "button"; - return ; + return ( + + ); }); Button.displayName = "Button"; diff --git a/web/src/index.css b/web/src/index.css index 9f68b0ec53b95..ca2041d565c61 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -369,4 +369,37 @@ .leaflet-popup-tip { background-color: var(--background) !important; } + + /* ======================================== + * Button Icon Divider Styles + * Adds vertical divider to buttons with dropdown triggers + * ======================================== */ + + /* Scope to buttons with dropdown menu triggers */ + button[data-slot="button"] [data-slot="dropdown-menu-trigger"] { + position: relative; + display: inline-flex; + align-items: center; + margin-left: 6px; /* space before divider */ + padding-left: 8px; /* space after divider */ + } + + /* Vertical divider */ + button[data-slot="button"] [data-slot="dropdown-menu-trigger"]::before { + content: ""; + position: absolute; + left: 0; + top: 50%; + transform: translateY(-50%); + width: 1px; + height: 1.25em; /* tweak to taste */ + background-color: currentColor; /* matches text color */ + opacity: 0.4; /* subtle */ + pointer-events: none; + } + + /* Ensure scrollbar space is always reserved */ + html { + overflow-y: scroll; + } }