Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/web/src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,7 @@ export default function Sidebar() {
render={<div role="button" tabIndex={0} />}
size="sm"
isActive={isActive}
className={`h-7 w-full translate-x-0 cursor-default justify-start px-2 text-left select-none hover:bg-accent hover:text-foreground focus-visible:ring-0 ${
className={`h-7 w-full translate-x-0 justify-start px-2 text-left select-none hover:bg-accent hover:text-foreground focus-visible:ring-0 ${
isSelected
? "bg-primary/15 text-foreground dark:bg-primary/10"
: isActive
Expand Down
53 changes: 53 additions & 0 deletions apps/web/src/components/ui/sidebar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it } from "vitest";

import {
SidebarMenuAction,
SidebarMenuButton,
SidebarMenuSubButton,
SidebarProvider,
} from "./sidebar";

function renderSidebarButton(className?: string) {
return renderToStaticMarkup(
<SidebarProvider>
<SidebarMenuButton className={className}>Projects</SidebarMenuButton>
</SidebarProvider>,
);
}

describe("sidebar interactive cursors", () => {
it("uses a pointer cursor for menu buttons by default", () => {
const html = renderSidebarButton();

expect(html).toContain('data-slot="sidebar-menu-button"');
expect(html).toContain("cursor-pointer");
});

it("lets project drag handles override the default pointer cursor", () => {
const html = renderSidebarButton("cursor-grab");

expect(html).toContain("cursor-grab");
expect(html).not.toContain("cursor-pointer");
});

it("uses a pointer cursor for menu actions", () => {
const html = renderToStaticMarkup(
<SidebarMenuAction aria-label="Create thread">
<span>+</span>
</SidebarMenuAction>,
);

expect(html).toContain('data-slot="sidebar-menu-action"');
expect(html).toContain("cursor-pointer");
});

it("uses a pointer cursor for submenu buttons", () => {
const html = renderToStaticMarkup(
<SidebarMenuSubButton render={<button type="button" />}>Show more</SidebarMenuSubButton>,
);

expect(html).toContain('data-slot="sidebar-menu-sub-button"');
expect(html).toContain("cursor-pointer");
});
});
6 changes: 3 additions & 3 deletions apps/web/src/components/ui/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
}

const sidebarMenuButtonVariants = cva(
"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-lg p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pe-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0",
"peer/menu-button flex w-full cursor-pointer items-center gap-2 overflow-hidden rounded-lg p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pe-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0",
{
defaultVariants: {
size: "default",
Expand Down Expand Up @@ -832,7 +832,7 @@ function SidebarMenuAction({
}) {
const defaultProps = {
className: cn(
"absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-lg p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0",
"absolute top-1.5 right-1 flex aspect-square w-5 cursor-pointer items-center justify-center rounded-lg p-0 text-sidebar-foreground outline-hidden ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0",
// Increases the hit area of the button on mobile.
"after:-inset-2 after:absolute md:after:hidden",
"peer-data-[size=sm]/menu-button:top-1",
Expand Down Expand Up @@ -944,7 +944,7 @@ function SidebarMenuSubButton({
}) {
const defaultProps = {
className: cn(
"-translate-x-px flex h-7 min-w-0 items-center gap-2 overflow-hidden rounded-lg px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
"-translate-x-px flex h-7 min-w-0 cursor-pointer items-center gap-2 overflow-hidden rounded-lg px-2 text-sidebar-foreground outline-hidden ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg:not([class*='size-'])]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
size === "sm" && "text-xs",
size === "md" && "text-sm",
Expand Down
Loading