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(