diff --git a/apps/storybook/src/Dropdown.stories.tsx b/apps/storybook/src/Dropdown.stories.tsx
index d93d1047c..e0a3fe9b3 100644
--- a/apps/storybook/src/Dropdown.stories.tsx
+++ b/apps/storybook/src/Dropdown.stories.tsx
@@ -129,3 +129,17 @@ ItemClickHandler.args = {
>
),
};
+
+export const onToggleHandler = Template.bind({});
+onToggleHandler.storyName = "onToggle handlers";
+onToggleHandler.args = {
+ onToggle: action("Dropdown toggled"),
+ children: (
+ <>
+ Dashboard
+ Settings
+ Earnings
+ Sign out
+ >
+ ),
+};
diff --git a/packages/ui/src/components/Dropdown/Dropdown.tsx b/packages/ui/src/components/Dropdown/Dropdown.tsx
index 296d0df15..88819c4d3 100644
--- a/packages/ui/src/components/Dropdown/Dropdown.tsx
+++ b/packages/ui/src/components/Dropdown/Dropdown.tsx
@@ -45,7 +45,7 @@ export interface DropdownTheme {
export interface DropdownProps
extends Pick,
- Omit>,
+ Omit | "onToggle">,
ThemingProps {
arrowIcon?: boolean;
dismissOnClick?: boolean;
@@ -54,6 +54,7 @@ export interface DropdownProps
label?: ReactNode;
enableTypeAhead?: boolean;
renderTrigger?: (theme: DropdownTheme) => ReactElement;
+ onToggle?: (open: boolean) => void;
"data-testid"?: string;
}
@@ -130,6 +131,7 @@ export function Dropdown(props: DropdownProps) {
dismissOnClick = true,
enableTypeAhead = true,
renderTrigger,
+ onToggle,
...restProps
} = resolveProps(props, provider.props?.dropdown);
@@ -143,10 +145,21 @@ export function Dropdown(props: DropdownProps) {
} = restProps;
const dataTestId = restProps["data-testid"] || "flowbite-dropdown-target";
- const handleSelect = useCallback((index: number | null) => {
- setSelectedIndex(index);
- setOpen(false);
- }, []);
+ const handleOpenChange = useCallback(
+ (newOpen: boolean) => {
+ setOpen(newOpen);
+ onToggle?.(newOpen);
+ },
+ [onToggle],
+ );
+
+ const handleSelect = useCallback(
+ (index: number | null) => {
+ setSelectedIndex(index);
+ handleOpenChange(false);
+ },
+ [handleOpenChange],
+ );
const handleTypeaheadMatch = useCallback(
(index: number | null) => {
@@ -161,7 +174,10 @@ export function Dropdown(props: DropdownProps) {
const { context, floatingStyles, refs } = useBaseFLoating({
open,
- setOpen,
+ setOpen: (value) => {
+ const newOpen = typeof value === "function" ? value(open) : value;
+ handleOpenChange(newOpen);
+ },
placement,
});