Skip to main content

Dropdown: React

An overlay list of options, which are hidden by default but can be shown by interacting with a button or other component.

Installation

Before you can start using the @mediahuis/chameleon-react component, you’ll need to install it, for more information check: Getting started for developers.

With that done, you’re now ready to implement the component in your application.

import { Dropdown, DropdownItem } from '@mediahuis/chameleon-react';

export default function Example() {
const anchorRef = React.useRef(null);

return (
<>
<Button ref={anchorRef}>Click here to open</Button>
<Dropdown anchorRef={anchorRef}>
<DropdownItem>
<Dropdown/>
</>
);
}
PropertyTypeDefaultRequiredDescription
anchorRefRefObject-YesReference to the element which you want to use for positioning of the dropdown.
childrenReactNode-NoThe children of the Dropdown component.
defaultOpenBooleanfalseNoDetermines the visibility state of the dropdown by default.
idString-YesSets the native HTML id attribute. It will also affect the describedby-id for accessibility reasons.
placementPlacement'bottom-start'NoDetermines where the Dropdown is positioned towards the target element.
PropertyTypeDefaultRequiredDescription
clickableBooleantrueNoDetermines if clickable styles are added when set to true.
iconRightElementType-NoControls the `as` prop of the Icon on the right side.
titleReactNode-YesThe text inside the DropdownItem.

Controlling the Dropdown Programmatically

The Dropdown component provides methods that let you control it from a parent component using a ref. This is useful when you need to programmatically open, close, or toggle the dropdown.

When you create a ref to the Dropdown component, you get access to three methods:

  • toggle(): Switches the dropdown between open and closed states
  • open(): Opens the dropdown
  • close(): Closes the dropdown
  • update(): Recalculates the position of the dropdown

Usage example

function ParentComponent() {
const dropdownRef = useRef(null);

const handleButtonClick = () => {
// You can call any of the exposed methods
dropdownRef.current.toggle();
// Or dropdownRef.current.open();
// Or dropdownRef.current.close();
};

return (
<>
<Button onClick={handleButtonClick}>Toggle Dropdown</Button>
<Dropdown ref={dropdownRef} anchorRef={buttonRef}>
{/* Dropdown content */}
</Dropdown>
</>
);
}

Updating dropdown position after DOM changes

When async content changes the DOM layout, the dropdown position may need manual updating. Use a mutation observer with the update() method:

import { useEffect, useRef } from 'react';
import { AsyncAd } from './AsyncAd';

function Example() {
const dropdownRef = useRef(null);
const wrapperRef = useRef(null);

useEffect(() => {
const observer = new MutationObserver(() => {
dropdownRef.current.update();
});

observer.observe(wrapperRef.current, {
childList: true,
subtree: true,
});

return () => {
observer.disconnect();
};
}, []);

return (
<div ref={wrapperRef}>
<AsyncAd />
<Button onClick={handleButtonClick}>Toggle Dropdown</Button>
<Dropdown ref={dropdownRef} anchorRef={buttonRef}>
<DropdownItem>Option 1</DropdownItem>
<DropdownItem>Option 2</DropdownItem>
<DropdownItem>Option 3</DropdownItem>
</Dropdown>
</div>
);
}