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/>
    </>
  );
}
Dropdown Properties
| Property | Type | Default | Required | Description | 
|---|---|---|---|---|
| anchorRef | RefObject | - | Yes | Reference to the element which you want to use for positioning of the dropdown. | 
| children | ReactNode | - | No | The children of the Dropdown component. | 
| defaultOpen | Boolean | false | No | Determines the visibility state of the dropdown by default. | 
| id | String | - | Yes | Sets the native HTML id attribute. It will also affect the describedby-id for accessibility reasons. | 
| placement | Placement | 'bottom-start' | No | Determines where the Dropdown is positioned towards the target element. | 
DropdownItem Properties
| Property | Type | Default | Required | Description | 
|---|---|---|---|---|
| clickable | Boolean | true | No | Determines if clickable styles are added when set to true. | 
| iconRight | ElementType | - | No | Controls the `as` prop of the Icon on the right side. | 
| title | ReactNode | - | Yes | The 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>
  );
}