Fleet UI: Dropdown always scrolled to view in userform (#24719)

This commit is contained in:
RachelElysia
2024-12-13 09:26:58 -05:00
committed by GitHub
parent a5726399cb
commit 6c79c07441
4 changed files with 26 additions and 5 deletions
@@ -54,7 +54,8 @@ export interface IDropdownWrapper {
isSearchable?: boolean;
isDisabled?: boolean;
placeholder?: string;
menuPortalTarget?: HTMLElement | null;
/** E.g. scroll to view dropdown menu in a scrollable parent container */
onMenuOpen?: () => void;
}
const baseClass = "dropdown-wrapper";
@@ -72,7 +73,7 @@ const DropdownWrapper = ({
isSearchable,
isDisabled = false,
placeholder,
menuPortalTarget,
onMenuOpen,
}: IDropdownWrapper) => {
const wrapperClassNames = classnames(baseClass, className);
@@ -326,12 +327,10 @@ const DropdownWrapper = ({
value={getCurrentValue()}
onChange={handleChange}
isDisabled={isDisabled}
menuPortalTarget={
menuPortalTarget === undefined ? document.body : menuPortalTarget
}
noOptionsMessage={() => "No results found"}
tabIndex={isDisabled ? -1 : 0} // Ensures disabled dropdown has no keyboard accessibility
placeholder={placeholder}
onMenuOpen={onMenuOpen}
/>
</FormField>
);
@@ -13,6 +13,7 @@ interface ISelectRoleFormProps {
teams: ITeam[];
onFormChange: (teams: ITeam[]) => void;
isApiOnly?: boolean;
onMenuOpen?: () => void;
}
const generateSelectedTeamData = (
@@ -33,6 +34,7 @@ const SelectRoleForm = ({
teams,
onFormChange,
isApiOnly,
onMenuOpen,
}: ISelectRoleFormProps): JSX.Element => {
const { isPremiumTier } = useContext(AppContext);
@@ -60,6 +62,7 @@ const SelectRoleForm = ({
value={selectedRole}
onChange={updateSelectedRole}
isSearchable={false}
onMenuOpen={onMenuOpen}
/>
);
};
@@ -17,6 +17,7 @@ interface ISelectedTeamsFormProps {
usersCurrentTeams: ITeam[];
onFormChange: (teams: ITeam[]) => void;
isApiOnly?: boolean;
onMenuOpen?: () => void;
}
const baseClass = "selected-teams-form";
@@ -106,6 +107,7 @@ const SelectedTeamsForm = ({
usersCurrentTeams,
onFormChange,
isApiOnly,
onMenuOpen,
}: ISelectedTeamsFormProps): JSX.Element => {
const [teamsFormList, updateSelectedTeams] = useSelectedTeamState(
availableTeams,
@@ -137,6 +139,7 @@ const SelectedTeamsForm = ({
onChange={(newValue: SingleValue<CustomOptionType>) =>
updateSelectedTeams(teamItem.id, newValue as CustomOptionType)
}
onMenuOpen={onMenuOpen}
/>
</div>
);
@@ -166,6 +166,19 @@ const UserForm = ({
};
};
// Used to show entire dropdown when a dropdown menu is open in scrollable component of a modal
// menuPortalTarget solution not used as scrolling is weird
const scrollToFitDropdownMenu = () => {
if (topDivRef?.current) {
setTimeout(() => {
if (topDivRef.current) {
topDivRef.current.scrollTop =
topDivRef.current.scrollHeight - topDivRef.current.clientHeight;
}
}, 50); // Delay needed for scrollHeight to update first
}
};
const onCheckboxChange = (formField: string): ((evt: string) => void) => {
return (evt: string) => {
return onInputChange(formField)(evt);
@@ -318,6 +331,7 @@ const UserForm = ({
}
}}
isSearchable={false}
onMenuOpen={scrollToFitDropdownMenu}
/>
</>
);
@@ -366,6 +380,7 @@ const UserForm = ({
usersCurrentTeams={formData.teams}
onFormChange={onSelectedTeamChange}
isApiOnly={isApiOnly}
onMenuOpen={scrollToFitDropdownMenu}
/>
</>
) : (
@@ -375,6 +390,7 @@ const UserForm = ({
defaultTeamRole={defaultTeamRole || "Observer"}
onFormChange={onTeamRoleChange}
isApiOnly={isApiOnly}
onMenuOpen={scrollToFitDropdownMenu}
/>
))}
{!availableTeams.length && renderNoTeamsMessage()}