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, });