Skip to content

Commit

Permalink
fix: react-combobox listbox popup width matches trigger width (#24733)
Browse files Browse the repository at this point in the history
  • Loading branch information
smhigley authored Sep 12, 2022
1 parent 58026c9 commit 83b033d
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "fix: set popup Listbox width to trigger width",
"packageName": "@fluentui/react-combobox",
"email": "sarah.higley@microsoft.com",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ exports[`Combobox renders an open listbox 1`] = `
<div
class="fui-Listbox fui-Combobox__listbox"
role="listbox"
style="position: fixed; left: 0px; top: 0px; margin: 0px;"
style="position: fixed; left: 0px; top: 0px; margin: 0px; width: 0px;"
>
<div
aria-selected="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,17 @@ export const useCombobox_unstable = (props: ComboboxProps, ref: React.Ref<HTMLIn
excludedPropNames: ['children', 'size'],
});

const rootRef = React.useRef<HTMLDivElement>(null);
const triggerRef = React.useRef<HTMLInputElement>(null);

// calculate listbox width style based on trigger width
const [popupWidth, setPopupWidth] = React.useState<string>();
React.useEffect(() => {
const width = open ? `${rootRef.current?.clientWidth}px` : undefined;
setPopupWidth(width);
}, [open]);

// handle input type-to-select
const getSearchString = (inputValue: string): string => {
// if there are commas in the value string, take the text after the last comma
const searchString = inputValue.split(',').pop();
Expand Down Expand Up @@ -153,7 +162,10 @@ export const useCombobox_unstable = (props: ComboboxProps, ref: React.Ref<HTMLIn
open || hasFocus
? resolveShorthand(props.listbox, {
required: true,
defaultProps: { children: props.children },
defaultProps: {
children: props.children,
style: { width: popupWidth },
},
})
: undefined;

Expand Down Expand Up @@ -185,6 +197,8 @@ export const useCombobox_unstable = (props: ComboboxProps, ref: React.Ref<HTMLIn
setOpen,
};

state.root.ref = useMergedRefs(state.root.ref, rootRef);

/* handle open/close + focus change when clicking expandIcon */
const { onMouseDown: onIconMouseDown, onClick: onIconClick } = state.expandIcon || {};
const onExpandIconMouseDown = useEventCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ exports[`Dropdown renders an open listbox 1`] = `
<div
class="fui-Listbox fui-Dropdown__listbox"
role="listbox"
style="position: fixed; left: 0px; top: 0px; margin: 0px;"
style="position: fixed; left: 0px; top: 0px; margin: 0px; width: 0px;"
>
<div
aria-selected="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Listbox } from '../Listbox/Listbox';
import type { Slot } from '@fluentui/react-utilities';
import type { OptionValue } from '../../utils/OptionCollection.types';
import type { DropdownProps, DropdownState } from './Dropdown.types';
import { useMergedRefs } from '@fluentui/react-utilities';

/**
* Create the state required to render Dropdown.
Expand Down Expand Up @@ -37,6 +38,14 @@ export const useDropdown_unstable = (props: DropdownProps, ref: React.Ref<HTMLBu
excludedPropNames: ['children'],
});

// set listbox popup width based off the root/trigger width
const rootRef = React.useRef<HTMLDivElement>(null);
const [popupWidth, setPopupWidth] = React.useState<string>();
React.useEffect(() => {
const width = open ? `${rootRef.current?.clientWidth}px` : undefined;
setPopupWidth(width);
}, [open]);

// jump to matching option based on typing
const searchString = React.useRef('');
const [setKeyTimeout, clearKeyTimeout] = useTimeout();
Expand Down Expand Up @@ -117,7 +126,10 @@ export const useDropdown_unstable = (props: DropdownProps, ref: React.Ref<HTMLBu
baseState.open || baseState.hasFocus
? resolveShorthand(props.listbox, {
required: true,
defaultProps: { children: props.children },
defaultProps: {
children: props.children,
style: { width: popupWidth },
},
})
: undefined;

Expand Down Expand Up @@ -150,5 +162,7 @@ export const useDropdown_unstable = (props: DropdownProps, ref: React.Ref<HTMLBu
...baseState,
};

state.root.ref = useMergedRefs(state.root.ref, rootRef);

return state;
};

0 comments on commit 83b033d

Please sign in to comment.