1- import {
2- ArrowTopRightOnSquareIcon ,
3- ChevronRightIcon ,
4- ExclamationTriangleIcon ,
5- } from "@heroicons/react/24/outline" ;
1+ import { ArrowTopRightOnSquareIcon , ExclamationTriangleIcon } from "@heroicons/react/24/outline" ;
62import { EllipsisHorizontalIcon } from "@heroicons/react/20/solid" ;
73import {
84 Form ,
@@ -135,7 +131,7 @@ import {
135131import { FreePlanUsage } from "../billing/FreePlanUsage" ;
136132import { ConnectionIcon , DevPresencePanel , useDevPresence } from "../DevPresence" ;
137133import { AlphaBadge , NewBadge } from "../FeatureBadges" ;
138- import { Button , ButtonContent , LinkButton } from "../primitives/Buttons" ;
134+ import { Button , LinkButton } from "../primitives/Buttons" ;
139135import { Dialog , DialogTrigger } from "../primitives/Dialog" ;
140136import { type RenderIcon } from "../primitives/Icon" ;
141137import { Paragraph } from "../primitives/Paragraph" ;
@@ -158,6 +154,7 @@ import {
158154} from "../primitives/Tooltip" ;
159155import { ShortcutsAutoOpen } from "../Shortcuts" ;
160156import { type FavoritePage } from "~/services/dashboardPreferences.server" ;
157+ import { AppearanceMenuItem } from "./AppearanceMenuItem" ;
161158import {
162159 CustomizeSidebarDialog ,
163160 type CustomizeSidebarSection ,
@@ -178,6 +175,7 @@ import { HelpAndFeedback } from "./HelpAndFeedbackPopover";
178175import { NotificationPanel } from "./NotificationPanel" ;
179176import { SideMenuHeader } from "./SideMenuHeader" ;
180177import { SideMenuItem , SideMenuLabel } from "./SideMenuItem" ;
178+ import { SideMenuPopoverSubMenu } from "./SideMenuPopoverSubMenu" ;
181179import { SideMenuSection } from "./SideMenuSection" ;
182180import {
183181 isItemHidden ,
@@ -1898,6 +1896,7 @@ function AccountMenuItems({
18981896 leadingIconClassName = { SIDE_MENU_POPOVER_ITEM_ICON }
18991897 className = { SIDE_MENU_POPOVER_ITEM_LABEL }
19001898 />
1899+ < AppearanceMenuItem />
19011900 < PopoverMenuItem
19021901 to = { personalAccessTokensPath ( ) }
19031902 title = "Personal Access Tokens"
@@ -2102,80 +2101,6 @@ function ProjectSelector({
21022101 ) ;
21032102}
21042103
2105- /**
2106- * Hover-expandable submenu row for side-menu popovers (Account, Switch organization, Integrations):
2107- * a menu item with a trailing chevron that reveals `children` in a popover to the right, with a
2108- * short close delay so the pointer can cross the gap.
2109- */
2110- function SideMenuPopoverSubMenu ( {
2111- title,
2112- icon,
2113- leadingIconClassName,
2114- children,
2115- } : {
2116- title : string ;
2117- icon : RenderIcon ;
2118- leadingIconClassName ?: string ;
2119- children : ReactNode ;
2120- } ) {
2121- const navigation = useNavigation ( ) ;
2122- const [ isOpen , setIsOpen ] = useState ( false ) ;
2123- const timeoutRef = useRef < NodeJS . Timeout | null > ( null ) ;
2124-
2125- useEffect ( ( ) => {
2126- return ( ) => {
2127- if ( timeoutRef . current ) clearTimeout ( timeoutRef . current ) ;
2128- } ;
2129- } , [ ] ) ;
2130-
2131- // Close the submenu on navigation (the parent popover closes too).
2132- useEffect ( ( ) => {
2133- setIsOpen ( false ) ;
2134- } , [ navigation . location ?. pathname ] ) ;
2135-
2136- const openNow = ( ) => {
2137- if ( timeoutRef . current ) clearTimeout ( timeoutRef . current ) ;
2138- setIsOpen ( true ) ;
2139- } ;
2140- const closeSoon = ( ) => {
2141- // Small delay before closing so the pointer can move onto the content.
2142- timeoutRef . current = setTimeout ( ( ) => setIsOpen ( false ) , 150 ) ;
2143- } ;
2144-
2145- return (
2146- < Popover onOpenChange = { ( open ) => setIsOpen ( open ) } open = { isOpen } >
2147- < div onMouseEnter = { openNow } onMouseLeave = { closeSoon } className = "flex" >
2148- < PopoverTrigger className = "w-full justify-between overflow-hidden focus-custom" >
2149- < ButtonContent
2150- variant = "small-menu-item"
2151- className = { cn ( "hover:bg-background-hover" , SIDE_MENU_POPOVER_ITEM_LABEL ) }
2152- LeadingIcon = { icon }
2153- leadingIconClassName = { cn ( SIDE_MENU_POPOVER_ITEM_ICON , leadingIconClassName ) }
2154- TrailingIcon = { ChevronRightIcon }
2155- trailingIconClassName = "text-text-dimmed"
2156- textAlignLeft
2157- fullWidth
2158- >
2159- { title }
2160- </ ButtonContent >
2161- </ PopoverTrigger >
2162- < PopoverContent
2163- className = "min-w-64 overflow-y-auto p-0 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
2164- align = "start"
2165- style = { { maxHeight : `calc(var(--radix-popover-content-available-height) - 10vh)` } }
2166- side = "right"
2167- alignOffset = { 0 }
2168- sideOffset = { - 4 }
2169- onMouseEnter = { openNow }
2170- onMouseLeave = { closeSoon }
2171- >
2172- { children }
2173- </ PopoverContent >
2174- </ div >
2175- </ Popover >
2176- ) ;
2177- }
2178-
21792104function SwitchOrganizations ( {
21802105 organizations,
21812106 organization,
0 commit comments