UI: fix accessibility issues

This commit is contained in:
Fuma Nama
2026-02-19 23:16:52 +08:00
parent 3f8c9b0ed9
commit 8f8e7f0ea3
6 changed files with 66 additions and 58 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'fumadocs-ui': patch
'@fumadocs/base-ui': patch
---
fix accessibility issues
@@ -45,11 +45,11 @@ const NavigationMenuContent = React.forwardRef<
cn(
'size-full p-4',
'transition-[opacity,transform,translate] duration-(--duration) ease-(--easing)',
'data-[starting-style]:opacity-0 data-[ending-style]:opacity-0',
'data-[starting-style]:data-[activation-direction=left]:-translate-x-1/2',
'data-[starting-style]:data-[activation-direction=right]:translate-x-1/2',
'data-[ending-style]:data-[activation-direction=left]:translate-x-1/2',
'data-[ending-style]:data-[activation-direction=right]:-translate-x-1/2',
'data-starting-style:opacity-0 data-ending-style:opacity-0',
'data-starting-style:data-[activation-direction=left]:-translate-x-1/2',
'data-starting-style:data-[activation-direction=right]:translate-x-1/2',
'data-ending-style:data-[activation-direction=left]:translate-x-1/2',
'data-ending-style:data-[activation-direction=right]:-translate-x-1/2',
typeof className === 'function' ? className(s) : className,
)
}
+9 -9
View File
@@ -73,18 +73,18 @@ export function Header({
transparentMode={nav.transparentMode}
className={cn(s.open && 'shadow-lg rounded-b-2xl')}
>
<NavigationMenuList className="flex h-14 w-full items-center px-4">
<div className="flex h-14 w-full items-center px-4">
{renderTitleNav(nav, {
className: 'inline-flex items-center gap-2.5 font-semibold',
})}
{nav.children}
<ul className="flex flex-row items-center gap-2 px-6 max-sm:hidden">
<NavigationMenuList className="flex flex-row items-center gap-2 px-6 max-sm:hidden">
{navItems
.filter((item) => !isSecondary(item))
.map((item, i) => (
<NavigationMenuLinkItem key={i} item={item} className="text-sm" />
))}
</ul>
</NavigationMenuList>
<div className="flex flex-row items-center justify-end gap-1.5 flex-1 max-lg:hidden">
{searchToggle.enabled !== false &&
(searchToggle.components?.lg ?? (
@@ -100,7 +100,7 @@ export function Header({
<Languages className="size-5" />
</LanguageToggle>
)}
<ul className="flex flex-row gap-2 items-center empty:hidden">
<NavigationMenuList className="flex flex-row gap-2 items-center empty:hidden">
{navItems.filter(isSecondary).map((item, i) => (
<NavigationMenuLinkItem
key={i}
@@ -108,9 +108,9 @@ export function Header({
item={item}
/>
))}
</ul>
</NavigationMenuList>
</div>
<ul className="flex flex-row items-center ms-auto -me-1.5 lg:hidden">
<div className="flex flex-row items-center ms-auto -me-1.5 lg:hidden">
{searchToggle.enabled !== false &&
(searchToggle.components?.sm ?? <SearchToggle className="p-2" hideIfDisabled />)}
<CollapsibleTrigger
@@ -125,8 +125,8 @@ export function Header({
>
<ChevronDown className="transition-transform duration-300 group-data-panel-open:rotate-180" />
</CollapsibleTrigger>
</ul>
</NavigationMenuList>
</div>
</div>
<CollapsibleContent className="flex flex-col px-4">
{menuItems
.filter((item) => !isSecondary(item))
@@ -243,7 +243,7 @@ function HeaderRoot({
}
function NavigationMenuLinkItem({ item, ...props }: { item: LinkItemType; className?: string }) {
if (item.type === 'custom') return <div {...props}>{item.children}</div>;
if (item.type === 'custom') return item.children;
if (item.type === 'menu') {
const children = item.items.map((child, j) => {
+1 -1
View File
@@ -36,7 +36,7 @@ export function NavbarMenuTrigger({ className, ...props }: NavigationMenuTrigger
className={(s) =>
cn(
navItemVariants(),
'rounded-md',
'text-sm rounded-md',
typeof className === 'function' ? className(s) : className,
)
}
+44 -42
View File
@@ -89,51 +89,53 @@ export function Header({
))}
</ul>
</div>
<ul className="flex flex-row items-center ms-auto -me-1.5 lg:hidden">
<div className="flex flex-row items-center ms-auto -me-1.5 lg:hidden">
{searchToggle.enabled !== false &&
(searchToggle.components?.sm ?? <SearchToggle className="p-2" hideIfDisabled />)}
<NavigationMenuItem>
<NavigationMenuTrigger
aria-label="Toggle Menu"
className={cn(
buttonVariants({
size: 'icon',
color: 'ghost',
className: 'group [&_svg]:size-5.5',
}),
)}
onPointerMove={nav.enableHoverToOpen ? undefined : (e) => e.preventDefault()}
>
<ChevronDown className="transition-transform duration-300 group-data-[state=open]:rotate-180" />
</NavigationMenuTrigger>
<NavigationMenuContent className="flex flex-col p-4 sm:flex-row sm:items-center sm:justify-end">
{menuItems
.filter((item) => !isSecondary(item))
.map((item, i) => (
<MobileNavigationMenuLinkItem key={i} item={item} className="sm:hidden" />
))}
<div className="-ms-1.5 flex flex-row items-center gap-2 max-sm:mt-2">
{menuItems.filter(isSecondary).map((item, i) => (
<MobileNavigationMenuLinkItem
key={i}
item={item}
className={cn(item.type === 'icon' && '-mx-1 first:ms-0')}
/>
))}
<div role="separator" className="flex-1" />
{i18n && (
<LanguageToggle>
<Languages className="size-5" />
<LanguageToggleText />
<ChevronDown className="size-3 text-fd-muted-foreground" />
</LanguageToggle>
<NavigationMenuItem asChild>
<div>
<NavigationMenuTrigger
aria-label="Toggle Menu"
className={cn(
buttonVariants({
size: 'icon',
color: 'ghost',
className: 'group [&_svg]:size-5.5',
}),
)}
{themeSwitch.enabled !== false &&
(themeSwitch.component ?? <ThemeToggle mode={themeSwitch?.mode} />)}
</div>
</NavigationMenuContent>
onPointerMove={nav.enableHoverToOpen ? undefined : (e) => e.preventDefault()}
>
<ChevronDown className="transition-transform duration-300 group-data-[state=open]:rotate-180" />
</NavigationMenuTrigger>
<NavigationMenuContent className="flex flex-col p-4 sm:flex-row sm:items-center sm:justify-end">
{menuItems
.filter((item) => !isSecondary(item))
.map((item, i) => (
<MobileNavigationMenuLinkItem key={i} item={item} className="sm:hidden" />
))}
<div className="-ms-1.5 flex flex-row items-center gap-2 max-sm:mt-2">
{menuItems.filter(isSecondary).map((item, i) => (
<MobileNavigationMenuLinkItem
key={i}
item={item}
className={cn(item.type === 'icon' && '-mx-1 first:ms-0')}
/>
))}
<div role="separator" className="flex-1" />
{i18n && (
<LanguageToggle>
<Languages className="size-5" />
<LanguageToggleText />
<ChevronDown className="size-3 text-fd-muted-foreground" />
</LanguageToggle>
)}
{themeSwitch.enabled !== false &&
(themeSwitch.component ?? <ThemeToggle mode={themeSwitch?.mode} />)}
</div>
</NavigationMenuContent>
</div>
</NavigationMenuItem>
</ul>
</div>
</HeaderNavigationMenu>
);
}
@@ -176,7 +178,7 @@ function HeaderNavigationMenu({
}
function NavigationMenuLinkItem({ item, ...props }: { item: LinkItemType; className?: string }) {
if (item.type === 'custom') return <div {...props}>{item.children}</div>;
if (item.type === 'custom') return item.children;
if (item.type === 'menu') {
const children = item.items.map((child, j) => {
@@ -28,7 +28,7 @@ export function NavbarMenuTrigger(props: NavigationMenuTriggerProps) {
return (
<NavigationMenuTrigger
{...props}
className={cn(navItemVariants(), 'rounded-md', props.className)}
className={cn(navItemVariants(), 'text-sm rounded-md', props.className)}
>
{props.children}
</NavigationMenuTrigger>