Skip to content

Commit d13c77c

Browse files
fix(dropdown): fix dropdown menu items container width (#714)
* fix(dropdown): fix dropdown menu items container width Resolves an issue where the content of `<Dropdown>`s didn't match the width of the `<Button>` trigger that opens the dropdown menu. #575 * fix(dropdown): fix dropdown menu items container width #575 * fix(dropdown): fix merge conflict #575 * fix(dropdown): fix useEffect has a missing dependency #575 * fix(dropdown): fix dropdown menu items container width #575 --------- Co-authored-by: [email protected] <[email protected]>
1 parent 57cf6e8 commit d13c77c

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/lib/components/Dropdown/Dropdown.tsx

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
/* eslint-disable react-hooks/exhaustive-deps */
12
/* eslint-disable @typescript-eslint/ban-ts-comment */
2-
import type { ComponentProps, FC, PropsWithChildren, ReactElement, ReactNode } from 'react';
3-
import React, { Children, useCallback, useMemo, useState } from 'react';
3+
import type { ComponentProps, Dispatch, FC, PropsWithChildren, ReactElement, ReactNode, SetStateAction } from 'react';
4+
import React, { Children, useCallback, useEffect, useMemo, useRef, useState } from 'react';
45
import { HiOutlineChevronDown, HiOutlineChevronLeft, HiOutlineChevronRight, HiOutlineChevronUp } from 'react-icons/hi';
56
import type { DeepPartial } from '..';
67
import { mergeDeep } from '../../helpers/mergeDeep';
@@ -43,6 +44,10 @@ export interface DropdownProps
4344
theme?: DeepPartial<FlowbiteDropdownTheme>;
4445
}
4546

47+
export interface TriggerWrapperProps extends ButtonProps {
48+
setButtonWidth?: Dispatch<SetStateAction<number | undefined>>;
49+
}
50+
4651
const icons: Record<string, FC<ComponentProps<'svg'>>> = {
4752
top: HiOutlineChevronUp,
4853
right: HiOutlineChevronRight,
@@ -75,6 +80,7 @@ const DropdownComponent: FC<DropdownProps> = ({
7580
}, [placement]);
7681

7782
const [closeRequestKey, setCloseRequestKey] = useState<string | undefined>(undefined);
83+
const [buttonWidth, setButtonWidth] = useState<number | undefined>(undefined);
7884

7985
// Extends DropdownItem's onClick to trigger a close request to the Floating component
8086
const attachCloseListener = useCallback(
@@ -105,8 +111,23 @@ const DropdownComponent: FC<DropdownProps> = ({
105111
[attachCloseListener, children, theme.content],
106112
);
107113

108-
const TriggerWrapper: FC<ButtonProps> = ({ children }) =>
109-
inline ? <button className={theme.inlineWrapper}>{children}</button> : <Button {...buttonProps}>{children}</Button>;
114+
const TriggerWrapper: FC<TriggerWrapperProps> = ({ children, setButtonWidth }): JSX.Element => {
115+
const ref = useRef<HTMLButtonElement | null>(null);
116+
117+
useEffect(() => {
118+
if (ref.current) setButtonWidth?.(ref.current.clientWidth);
119+
}, [ref]);
120+
121+
return inline ? (
122+
<button ref={ref} className={theme.inlineWrapper}>
123+
{children}
124+
</button>
125+
) : (
126+
<Button ref={ref} {...buttonProps}>
127+
{children}
128+
</Button>
129+
);
130+
};
110131

111132
return (
112133
<Floating
@@ -119,8 +140,9 @@ const DropdownComponent: FC<DropdownProps> = ({
119140
theme={theme.floating}
120141
closeRequestKey={closeRequestKey}
121142
className={className}
143+
minWidth={buttonWidth}
122144
>
123-
<TriggerWrapper>
145+
<TriggerWrapper setButtonWidth={setButtonWidth}>
124146
{label}
125147
{arrowIcon && <Icon className={theme.arrowIcon} />}
126148
</TriggerWrapper>

src/lib/components/Floating/Floating.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export interface FloatingProps extends PropsWithChildren<Omit<ComponentProps<'di
4747
style?: 'dark' | 'light' | 'auto';
4848
theme: FlowbiteFloatingTheme;
4949
trigger?: 'hover' | 'click';
50+
minWidth?: number;
5051
}
5152

5253
/**
@@ -63,6 +64,7 @@ export const Floating: FC<FloatingProps> = ({
6364
style = 'dark',
6465
theme,
6566
trigger = 'hover',
67+
minWidth,
6668
...props
6769
}) => {
6870
const arrowRef = useRef<HTMLDivElement>(null);
@@ -127,6 +129,7 @@ export const Floating: FC<FloatingProps> = ({
127129
position: strategy,
128130
top: y ?? ' ',
129131
left: x ?? ' ',
132+
minWidth,
130133
},
131134
...props,
132135
})}

0 commit comments

Comments
 (0)