Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
16 changes: 4 additions & 12 deletions apps/www/src/components/playground/drawer-examples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,28 @@ export function DrawerExamples() {
<PlaygroundLayout title='Drawer'>
<Flex gap='medium' wrap='wrap'>
<Drawer side='top'>
<Drawer.Trigger asChild>
<Button>Top Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Top Drawer</Drawer.Trigger>
<Drawer.Content side='top'>
<Drawer.Title>Top Drawer</Drawer.Title>
<Drawer.Description>Slides in from the Top</Drawer.Description>
</Drawer.Content>
</Drawer>
<Drawer side='right'>
<Drawer.Trigger asChild>
<Button>Right Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Right Drawer</Drawer.Trigger>
<Drawer.Content side='right'>
<Drawer.Title>Right Drawer</Drawer.Title>
<Drawer.Description>Slides in from the Right</Drawer.Description>
</Drawer.Content>
</Drawer>
<Drawer side='left'>
<Drawer.Trigger asChild>
<Button>Left Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Left Drawer</Drawer.Trigger>
<Drawer.Content side='left'>
<Drawer.Title>Left Drawer</Drawer.Title>
<Drawer.Description>Slides in from the Left</Drawer.Description>
</Drawer.Content>
</Drawer>
<Drawer side='bottom'>
<Drawer.Trigger asChild>
<Button>Bottom Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Bottom Drawer</Drawer.Trigger>
<Drawer.Content side='bottom'>
<Drawer.Title>Bottom Drawer</Drawer.Title>
<Drawer.Description>Slides in from the Bottom</Drawer.Description>
Expand Down
24 changes: 6 additions & 18 deletions apps/www/src/content/docs/components/drawer/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import { getPropsString } from '@/lib/utils';
export const getCode = (props: Record<string, unknown>) => {
return `
<Drawer${getPropsString(props)}>
<Drawer.Trigger>
<Button>Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Drawer</Drawer.Trigger>
<Drawer.Content${getPropsString(props)}>
<Drawer.Header>
<Drawer.Title>Drawer</Drawer.Title>
Expand Down Expand Up @@ -38,9 +36,7 @@ export const basicDemo = {
type: 'code',
code: `
<Drawer side="right">
<Drawer.Trigger>
<Button>Open Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Open Drawer</Drawer.Trigger>
<Drawer.Content>
<Drawer.Header>
<Drawer.Title>Drawer Title</Drawer.Title>
Expand All @@ -58,9 +54,7 @@ export const positionDemo = {
code: `
<Flex gap="medium">
<Drawer side="top">
<Drawer.Trigger>
<Button>Top Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Top Drawer</Drawer.Trigger>
<Drawer.Content side="top">
<Drawer.Header>
<Drawer.Title>Top Drawer</Drawer.Title>
Expand All @@ -70,9 +64,7 @@ export const positionDemo = {
</Drawer.Content>
</Drawer>
<Drawer side="right">
<Drawer.Trigger>
<Button>Right Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Right Drawer</Drawer.Trigger>
<Drawer.Content side="right">
<Drawer.Header>
<Drawer.Title>Right Drawer</Drawer.Title>
Expand All @@ -82,9 +74,7 @@ export const positionDemo = {
</Drawer.Content>
</Drawer>
<Drawer side="left">
<Drawer.Trigger>
<Button>Left Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Left Drawer</Drawer.Trigger>
<Drawer.Content side="left">
<Drawer.Header>
<Drawer.Title>Left Drawer</Drawer.Title>
Expand All @@ -94,9 +84,7 @@ export const positionDemo = {
</Drawer.Content>
</Drawer>
<Drawer side="bottom">
<Drawer.Trigger>
<Button>Bottom Drawer</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>Bottom Drawer</Drawer.Trigger>
<Drawer.Content side="bottom">
<Drawer.Header>
<Drawer.Title>Bottom Drawer</Drawer.Title>
Expand Down
3 changes: 2 additions & 1 deletion packages/raystack/components/alert-dialog/alert-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ export const AlertDialog = Object.assign(AlertDialogPrimitive.Root, {
Close: AlertDialogPrimitive.Close,
CloseButton: CloseButton,
Title: AlertDialogTitle,
Description: AlertDialogDescription
Description: AlertDialogDescription,
createHandle: AlertDialogPrimitive.createHandle
});
5 changes: 4 additions & 1 deletion packages/raystack/components/combobox/combobox.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Combobox as ComboboxPrimitive } from '@base-ui/react';
import { ComboboxContent } from './combobox-content';
import { ComboboxInput } from './combobox-input';
import { ComboboxItem } from './combobox-item';
Expand All @@ -14,5 +15,7 @@ export const Combobox = Object.assign(ComboboxRoot, {
Item: ComboboxItem,
Group: ComboboxGroup,
Label: ComboboxLabel,
Separator: ComboboxSeparator
Separator: ComboboxSeparator,
useFilter: ComboboxPrimitive.useFilter,
useFilteredItems: ComboboxPrimitive.useFilteredItems
});
3 changes: 2 additions & 1 deletion packages/raystack/components/dialog/dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ export const Dialog = Object.assign(DialogPrimitive.Root, {
Close: DialogPrimitive.Close,
CloseButton: CloseButton,
Title: DialogTitle,
Description: DialogDescription
Description: DialogDescription,
createHandle: DialogPrimitive.createHandle
});
8 changes: 2 additions & 6 deletions packages/raystack/components/drawer/__tests__/drawer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ const BasicDrawer = ({
side?: 'top' | 'right' | 'bottom' | 'left';
} & Record<string, unknown>) => (
<Drawer side={side} {...props}>
<Drawer.Trigger>
<Button>{TRIGGER_TEXT}</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>{TRIGGER_TEXT}</Drawer.Trigger>
<Drawer.Content side={side} showCloseButton={showCloseButton}>
<Drawer.Header>
<Drawer.Title>{DRAWER_TITLE}</Drawer.Title>
Expand Down Expand Up @@ -134,9 +132,7 @@ describe('Drawer', () => {
const user = userEvent.setup();
render(
<Drawer side='right'>
<Drawer.Trigger>
<Button>{TRIGGER_TEXT}</Button>
</Drawer.Trigger>
<Drawer.Trigger render={<Button />}>{TRIGGER_TEXT}</Drawer.Trigger>
<Drawer.Content className='custom-drawer'>
<Drawer.Header>
<Drawer.Title>{DRAWER_TITLE}</Drawer.Title>
Expand Down
2 changes: 1 addition & 1 deletion packages/raystack/components/drawer/drawer-content.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { DrawerPreview as DrawerPrimitive } from '@base-ui/react/drawer';
import { Drawer as DrawerPrimitive } from '@base-ui/react/drawer';
import { Cross1Icon } from '@radix-ui/react-icons';
import { cva, cx, type VariantProps } from 'class-variance-authority';
import { ReactNode } from 'react';
Expand Down
2 changes: 1 addition & 1 deletion packages/raystack/components/drawer/drawer-misc.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { DrawerPreview as DrawerPrimitive } from '@base-ui/react/drawer';
import { Drawer as DrawerPrimitive } from '@base-ui/react/drawer';
import { cx } from 'class-variance-authority';
import { ComponentProps, type ReactNode } from 'react';
import styles from './drawer.module.css';
Expand Down
2 changes: 1 addition & 1 deletion packages/raystack/components/drawer/drawer-root.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { DrawerPreview as DrawerPrimitive } from '@base-ui/react/drawer';
import { Drawer as DrawerPrimitive } from '@base-ui/react/drawer';

type Side = 'top' | 'right' | 'bottom' | 'left';

Expand Down
5 changes: 3 additions & 2 deletions packages/raystack/components/drawer/drawer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DrawerPreview as DrawerPrimitive } from '@base-ui/react/drawer';
import { Drawer as DrawerPrimitive } from '@base-ui/react/drawer';
import { DrawerContent } from './drawer-content';
import {
DrawerBody,
Expand All @@ -20,5 +20,6 @@ export const Drawer = Object.assign(DrawerRoot, {
Description: DrawerDescription,
Body: DrawerBody,
Footer: DrawerFooter,
Close: DrawerPrimitive.Close
Close: DrawerPrimitive.Close,
createHandle: DrawerPrimitive.createHandle
});
4 changes: 3 additions & 1 deletion packages/raystack/components/menu/menu.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Menu as MenuPrimitive } from '@base-ui/react/menu';
import { MenuContent, MenuSubContent } from './menu-content';
import { MenuItem } from './menu-item';
import {
Expand All @@ -19,5 +20,6 @@ export const Menu = Object.assign(MenuRoot, {
EmptyState: MenuEmptyState,
Submenu: MenuSubMenu,
SubmenuTrigger: MenuSubTrigger,
SubmenuContent: MenuSubContent
SubmenuContent: MenuSubContent,
createHandle: MenuPrimitive.createHandle
});
3 changes: 2 additions & 1 deletion packages/raystack/components/popover/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ PopoverContent.displayName = 'Popover.Content';
export const Popover = Object.assign(PopoverPrimitive.Root, {
Trigger: PopoverPrimitive.Trigger,
Close: PopoverPrimitive.Close,
Content: PopoverContent
Content: PopoverContent,
createHandle: PopoverPrimitive.createHandle
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function ScrollAreaScrollbar({
return (
<ScrollAreaPrimitive.Scrollbar
orientation={orientation}
keepMounted
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify forced mounting and where ScrollAreaScrollbar is instantiated without override.
rg -n --type=tsx 'keepMounted|ScrollAreaScrollbar\s+orientation=' \
  packages/raystack/components/scroll-area/scroll-area-scrollbar.tsx \
  packages/raystack/components/scroll-area/scroll-area.tsx

# Verify hidden-state CSS still allows pointer interactions.
rg -n --type=css 'scrollbar|opacity:\s*0|pointer-events' \
  packages/raystack/components/scroll-area/scroll-area.module.css

Repository: raystack/apsara

Length of output: 86


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List files to verify they exist
echo "=== Files to verify ==="
fd -e tsx -e css packages/raystack/components/scroll-area/

# Read scroll-area-scrollbar.tsx around Line 22
echo -e "\n=== scroll-area-scrollbar.tsx (Lines 1-35) ==="
cat -n packages/raystack/components/scroll-area/scroll-area-scrollbar.tsx | head -35

# Read the CSS file
echo -e "\n=== scroll-area.module.css (full content) ==="
cat -n packages/raystack/components/scroll-area/scroll-area.module.css

# Check scroll-area.tsx for ScrollAreaScrollbar usage
echo -e "\n=== scroll-area.tsx (full content) ==="
cat -n packages/raystack/components/scroll-area/scroll-area.tsx

Repository: raystack/apsara

Length of output: 569


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# List files in the directory correctly
echo "=== Files in scroll-area directory ==="
fd . 'packages/raystack/components/scroll-area/'

# Read scroll-area-scrollbar.tsx
echo -e "\n=== scroll-area-scrollbar.tsx ==="
cat -n packages/raystack/components/scroll-area/scroll-area-scrollbar.tsx

# Read scroll-area.module.css
echo -e "\n=== scroll-area.module.css ==="
cat -n packages/raystack/components/scroll-area/scroll-area.module.css

# Read scroll-area.tsx
echo -e "\n=== scroll-area.tsx ==="
cat -n packages/raystack/components/scroll-area/scroll-area.tsx

Repository: raystack/apsara

Length of output: 4782


Hardcoded keepMounted creates invisible interactive hitboxes on hidden scrollbars.

At Line 22, keepMounted is hardcoded with no option to override per-instance. Combined with your CSS where hidden modes use opacity: 0 (lines 71–73) while keeping pointer-events: auto (line 26), invisible scrollbars remain in the DOM and can intercept clicks near edges.

Make keepMounted configurable instead of forced:

Proposed fix
 export function ScrollAreaScrollbar({
   className,
   orientation = 'vertical',
   type = 'hover',
+  keepMounted = false,
   ...props
 }: ScrollAreaScrollbarProps) {
   return (
     <ScrollAreaPrimitive.Scrollbar
       orientation={orientation}
-      keepMounted
+      keepMounted={keepMounted}
       className={cx(styles.scrollbar, styles[`scrollbar-${type}`], className)}
       {...props}
     >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
keepMounted
export function ScrollAreaScrollbar({
className,
orientation = 'vertical',
type = 'hover',
keepMounted = false,
...props
}: ScrollAreaScrollbarProps) {
return (
<ScrollAreaPrimitive.Scrollbar
orientation={orientation}
keepMounted={keepMounted}
className={cx(styles.scrollbar, styles[`scrollbar-${type}`], className)}
{...props}
>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/raystack/components/scroll-area/scroll-area-scrollbar.tsx` at line
22, The ScrollAreaScrollbar component currently forces keepMounted (creating
invisible interactive hitboxes); make keepMounted a configurable prop on the
component (e.g., add keepMounted?: boolean to the component props and default it
to false), replace the hardcoded keepMounted usage with the prop (pass
props.keepMounted into the underlying Scrollbar/primitive where keepMounted was
hardcoded), and update any callsites to pass true where the old behavior is
required; also ensure CSS for hidden states still sets pointer-events
appropriately (or document that enabling keepMounted may require
pointer-events:none when hidden) so hidden scrollbars don't intercept clicks.

className={cx(styles.scrollbar, styles[`scrollbar-${type}`], className)}
{...props}
>
Expand Down
3 changes: 2 additions & 1 deletion packages/raystack/components/tooltip/tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ import { TooltipProvider, TooltipTrigger } from './tooltip-misc';
export const Tooltip = Object.assign(TooltipPrimitive.Root, {
Provider: TooltipProvider,
Trigger: TooltipTrigger,
Content: TooltipContent
Content: TooltipContent,
createHandle: TooltipPrimitive.createHandle
});
2 changes: 1 addition & 1 deletion packages/raystack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"vitest": "^3.2.4"
},
"dependencies": {
"@base-ui/react": "^1.2.0",
"@base-ui/react": "^1.3.0",
"@base-ui/utils": "^0.2.6",
"@radix-ui/react-icons": "^1.3.2",
"@tanstack/match-sorter-utils": "^8.8.4",
Expand Down
Loading
Loading