diff --git a/web/app/components/base/ui/dropdown-menu/__tests__/index.spec.tsx b/web/app/components/base/ui/dropdown-menu/__tests__/index.spec.tsx index 4ccf74209b..f0c0a0d019 100644 --- a/web/app/components/base/ui/dropdown-menu/__tests__/index.spec.tsx +++ b/web/app/components/base/ui/dropdown-menu/__tests__/index.spec.tsx @@ -179,6 +179,32 @@ describe('dropdown-menu wrapper', () => { expect(popup).toHaveClass('content-popup-custom') expect(screen.getByText('custom content')).toBeInTheDocument() }) + + it('should forward positioner and popup passthrough props when passthrough props are provided', () => { + // Arrange + + // Act + render( + + passthrough content + , + ) + + // Assert + const positioner = screen.getByTestId('menu-positioner') + const popup = screen.getByTestId('menu-popup') + expect(positioner).toHaveAttribute('aria-label', 'dropdown content positioner') + expect(popup).toHaveAttribute('role', 'menu') + expect(popup).toHaveAttribute('aria-label', 'dropdown content popup') + }) }) describe('DropdownMenuSubContent', () => { @@ -236,6 +262,32 @@ describe('dropdown-menu wrapper', () => { expect(positioner).toHaveClass('sub-positioner-custom') expect(popup).toHaveClass('sub-popup-custom') }) + + it('should forward passthrough props for sub-content positioner and popup when passthrough props are provided', () => { + // Arrange + + // Act + render( + + passthrough sub content + , + ) + + // Assert + const positioner = screen.getByTestId('menu-positioner') + const popup = screen.getByTestId('menu-popup') + expect(positioner).toHaveAttribute('aria-label', 'dropdown sub positioner') + expect(popup).toHaveAttribute('role', 'menu') + expect(popup).toHaveAttribute('aria-label', 'dropdown sub popup') + }) }) describe('DropdownMenuSubTrigger', () => { diff --git a/web/app/components/base/ui/popover/__tests__/index.spec.tsx b/web/app/components/base/ui/popover/__tests__/index.spec.tsx index d9176e26c0..c509d0eefb 100644 --- a/web/app/components/base/ui/popover/__tests__/index.spec.tsx +++ b/web/app/components/base/ui/popover/__tests__/index.spec.tsx @@ -17,6 +17,7 @@ type PositionerMockProps = ComponentPropsWithoutRef<'div'> & { const positionerPropsSpy = vi.fn<(props: PositionerMockProps) => void>() const popupClassNameSpy = vi.fn<(className: string | undefined) => void>() +const popupPropsSpy = vi.fn<(props: ComponentPropsWithoutRef<'div'>) => void>() const parsePlacementMock = vi.fn<(placement: Placement) => ParsedPlacement>() vi.mock('@base-ui/react/popover', () => { @@ -53,10 +54,11 @@ vi.mock('@base-ui/react/popover', () => { ) } - const Popup = ({ children, className }: ComponentPropsWithoutRef<'div'>) => { + const Popup = ({ children, className, ...props }: ComponentPropsWithoutRef<'div'>) => { popupClassNameSpy(className) + popupPropsSpy({ className, ...props }) return ( -
+
{children}
) @@ -168,6 +170,43 @@ describe('PopoverContent', () => { }) }) + describe('Passthrough props', () => { + it('should forward positionerProps and popupProps when passthrough props are provided', () => { + // Arrange + render( + + Popover body + , + ) + + // Act + const popup = screen.getByTestId('mock-popup') + + // Assert + expect(positionerPropsSpy).toHaveBeenCalledWith( + expect.objectContaining({ + 'aria-label': 'popover positioner', + }), + ) + expect(popupPropsSpy).toHaveBeenCalledWith( + expect.objectContaining({ + 'role': 'dialog', + 'aria-label': 'popover content', + }), + ) + expect(popup).toHaveAttribute('role', 'dialog') + expect(popup).toHaveAttribute('aria-label', 'popover content') + }) + }) + describe('Children rendering', () => { it('should render children inside Popup', () => { // Arrange diff --git a/web/app/components/base/ui/select/__tests__/index.spec.tsx b/web/app/components/base/ui/select/__tests__/index.spec.tsx index 386b25c4f2..ca7586c7e7 100644 --- a/web/app/components/base/ui/select/__tests__/index.spec.tsx +++ b/web/app/components/base/ui/select/__tests__/index.spec.tsx @@ -219,6 +219,38 @@ describe('Select wrappers', () => { expect(screen.getByTestId('base-select-list')).toHaveClass('max-h-80', 'custom-list') }) + it('should forward passthrough props to positioner popup and list when passthrough props are provided', () => { + // Arrange & Act + render( + +
Option A
+
, + ) + + // Assert + const positioner = screen.getByTestId('base-select-positioner') + const popup = screen.getByTestId('base-select-popup') + const list = screen.getByTestId('base-select-list') + + expect(positioner).toHaveAttribute('aria-label', 'select positioner') + expect(popup).toHaveAttribute('role', 'dialog') + expect(popup).toHaveAttribute('aria-label', 'select popup') + expect(list).toHaveAttribute('role', 'listbox') + expect(list).toHaveAttribute('aria-label', 'select list') + }) + it('should render children inside list when children are provided', () => { // Arrange & Act render(