diff --git a/client/src/components/Nav/AgentMarketplaceButton.tsx b/client/src/components/Nav/AgentMarketplaceButton.tsx index a9416d7cba2..7729cfbc0e0 100644 --- a/client/src/components/Nav/AgentMarketplaceButton.tsx +++ b/client/src/components/Nav/AgentMarketplaceButton.tsx @@ -2,13 +2,22 @@ import { Link } from 'react-router-dom'; import { LayoutGrid } from 'lucide-react'; import { Button, TooltipAnchor } from '@librechat/client'; import { useLocalize, useShowMarketplace } from '~/hooks'; +import { cn } from '~/utils'; interface AgentMarketplaceButtonProps { /** Which way the tooltip opens: the desktop rail is a left edge, the mobile - * drawer header is a top edge. */ + * drawer header is a top edge. Ignored by the `row` layout, which has no + * tooltip to place. */ side?: 'right' | 'bottom'; /** Mobile dismisses the drawer on navigation; the desktop rail stays put. */ onNavigate?: () => void; + /** + * `icon` is the rail's square, labelled by a tooltip. `row` is a full-width + * entry carrying its own label, for the mobile drawer: an icon in a header + * strip is the easiest thing there to miss, and the list it now heads is + * where someone already looks for somewhere to go. + */ + layout?: 'icon' | 'row'; } /** Agent Marketplace entry in the sidebar. Self-gated on marketplace @@ -16,6 +25,7 @@ interface AgentMarketplaceButtonProps { export default function AgentMarketplaceButton({ side = 'right', onNavigate, + layout = 'icon', }: AgentMarketplaceButtonProps) { const localize = useLocalize(); const showAgentMarketplace = useShowMarketplace(); @@ -24,33 +34,46 @@ export default function AgentMarketplaceButton({ return null; } + const isRow = layout === 'row'; + + /** Composed through the shared button so the focus ring, hover fill and theme + * timing come from the primitive rather than being restated: a hand-rolled + * version of this had no focus ring at all. `asChild` keeps it a router Link, + * so modifier- and middle-clicks still open the marketplace in a new tab, and + * those stay on the current page and so must not dismiss. */ + const button = ( + + ); + + if (isRow) { + return button; + } + return ( - - { - if (event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey) { - return; - } - onNavigate?.(); - }} - > -