ui
ui copied to clipboard
orientation="vertical" seems ignored on navigation menu
According to the Radix UI API documentation and Navigation Menu's Typescript, there's an orientation
prop that can be used to change the menu to "vertical"
. However, adding that option doesn't change anything.
<NavigationMenu orientation="vertical">
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>Item One</NavigationMenuTrigger>
<NavigationMenuContent>
<NavigationMenuLink>Link</NavigationMenuLink>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>Item One</NavigationMenuTrigger>
<NavigationMenuContent>
<NavigationMenuLink>Link</NavigationMenuLink>
</NavigationMenuContent>
</NavigationMenuItem>
<NavigationMenuItem>
<NavigationMenuTrigger>Item One</NavigationMenuTrigger>
<NavigationMenuContent>
<NavigationMenuLink>Link</NavigationMenuLink>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>
I think the orientation
prop changes the 'functional' orientation, not the 'visual' one (i.e. if up/down arrows or left/right arrows will navigate within the component). At least this is what I understand from https://github.com/radix-ui/website/pull/512 (another component, but I guess the idea is the same).
I do think, though, it would be nice to implement the visual orientation in this library as well. Will take a look into that and open a PR soon.
Ah, I do see the data attribute change to vertical for the children elements in the HTML. But yes, simply switching to flex-col
would be good.
used flex-col
for vertical orientation inside sheet.
If anyone came here looking for a vertical tab component here it is.
"use client";
import * as React from "react";
import { cn } from "@/lib/utils";
import * as TabsPrimitive from "@radix-ui/react-tabs";
const Tabs = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Root
orientation="vertical"
ref={ref}
className={cn(
"flex rounded-md p-1 border-3 border-white text-muted-foreground gap-1",
className
)}
{...props}
/>
));
Tabs.displayName = TabsPrimitive.List.displayName;
const TabsList = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.List>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.List>
>(({ className, ...props }, ref) => (
<TabsPrimitive.List
ref={ref}
className={cn(
"flex flex-col h-auto items-center justify-start rounded-md bg-muted p-1 text-muted-foreground",
className
)}
{...props}
/>
));
TabsList.displayName = TabsPrimitive.List.displayName;
const TabsTrigger = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Trigger
ref={ref}
className={cn(
"flex items-center justify-start whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
className
)}
{...props}
/>
));
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
const TabsContent = React.forwardRef<
React.ElementRef<typeof TabsPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>
>(({ className, ...props }, ref) => (
<TabsPrimitive.Content
ref={ref}
className={cn(
"ml-4 mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
className
)}
{...props}
/>
));
TabsContent.displayName = TabsPrimitive.Content.displayName;
export { Tabs, TabsContent, TabsList, TabsTrigger };
adding this class might be the quickest solution
This is great, but bringing this into the core Tabs component as per @arunavo4's implementation would be great. 👏🏼
adding this class might be the quickest solution
This doesn't fix the hover states on NavigationMenuContent
though. They seem to stay at the bottom of the container for me
I tried this way but the issue i am having is that the navigation menu list is being shown behind of other navigations menus.
As @heripurnama commented, adding 'flex-col' and 'items-start' helps. But, a least for me, I also had to include 'space-x-0' to remove a 4px margin left of all items except the first one.
- This is the result using just 'flex-col' and 'items-start'. Notice how the second and third items are slightly not aligned with the first one. They actually have a 4px margin left because of the 'space-x-1' style property used on the List component at navigation-menu.tsx:
- To remove that, just include 'space-x-0' along with 'flex-col' and 'items-start'
- If you prefer, you can insted, remove 'space-x-1' directly from the List component at navigation-menu.tsx:
Or even create a
For those who want a vertical menu, viewport displayed on the right, the following steps can be done with minimal code editing: For vertical menu:
- create vertical menu as @victorassiso and @heripurnama
<NavigationMenuList className="flex-col items-start space-x-0">
- add taildwind class to NavigationMenuTrigger for better looking menu
<NavigationMenuTrigger className="rounded-none capitalize w-60 pl-1 flex justify-between"> <span className="inline-flex items-center"> <SunDimIcon className="mr-2 h-4 w-4" /> {category.name.toLowerCase()} </span> </NavigationMenuTrigger>
For viewports:
- Disable reference to NavigationMenuViewport in NavigationMenu (navigation-menu.tsx)
... {children} {/*<NavigationMenuViewport />*/} </NavigationMenuPrimitive.Root>
- Change viewport position: just wrap NavigationMenuViewport in a div tag
<div className="absolute top-0 -mt-2 left-60">
<NavigationMenuViewport className="rounded-none" />
</div>
Example image:
This issue has been automatically closed because it received no activity for a while. If you think it was closed by accident, please leave a comment. Thank you.