mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-26 09:22:14 +00:00
Fix: Add support of auto positioning for tag's drop-down (#1169)
* Feat: add auto position feature for tag dropdown * increase buffer space by 50px
This commit is contained in:
parent
055f629cab
commit
04f1903481
@ -16,9 +16,11 @@
|
||||
*/
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { isNil, lowerCase } from 'lodash';
|
||||
import { isNil, isUndefined, lowerCase } from 'lodash';
|
||||
import React, { FunctionComponent, useEffect, useRef, useState } from 'react';
|
||||
import { useWindowDimensions } from '../../hooks/useWindowDimensions';
|
||||
import { getCountBadge } from '../../utils/CommonUtils';
|
||||
import { getTopPosition } from '../../utils/DropDownUtils';
|
||||
import { DropDownListItem, DropDownListProp } from './types';
|
||||
|
||||
const DropDownList: FunctionComponent<DropDownListProp> = ({
|
||||
@ -30,10 +32,15 @@ const DropDownList: FunctionComponent<DropDownListProp> = ({
|
||||
value,
|
||||
onSelect,
|
||||
groupType = 'label',
|
||||
domPosition,
|
||||
}: DropDownListProp) => {
|
||||
const { height: windowHeight } = useWindowDimensions();
|
||||
const isMounted = useRef<boolean>(false);
|
||||
const [searchedList, setSearchedList] = useState(dropDownList);
|
||||
const [searchText, setSearchText] = useState(searchString);
|
||||
const [dropDownPosition, setDropDownPosition] = useState<
|
||||
{ bottom: string } | {}
|
||||
>({});
|
||||
|
||||
const setCurrentTabOnMount = () => {
|
||||
const selectedItem = dropDownList.find((l) => l.value === value);
|
||||
@ -109,6 +116,14 @@ const DropDownList: FunctionComponent<DropDownListProp> = ({
|
||||
}
|
||||
}, [searchText]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isUndefined(domPosition)) {
|
||||
setDropDownPosition(
|
||||
getTopPosition(windowHeight, domPosition.bottom, domPosition.height)
|
||||
);
|
||||
}
|
||||
}, [domPosition, searchText]);
|
||||
|
||||
useEffect(() => {
|
||||
setActiveTab(setCurrentTabOnMount());
|
||||
isMounted.current = true;
|
||||
@ -134,7 +149,8 @@ const DropDownList: FunctionComponent<DropDownListProp> = ({
|
||||
horzPosRight ? 'dd-horz-right' : 'dd-horz-left'
|
||||
)}
|
||||
data-testid="dropdown-list"
|
||||
role="menu">
|
||||
role="menu"
|
||||
style={dropDownPosition}>
|
||||
{showSearchBar && (
|
||||
<div className="has-search tw-p-4 tw-pb-2">
|
||||
<input
|
||||
|
@ -53,6 +53,7 @@ export type DropDownListProp = {
|
||||
) => void;
|
||||
setIsOpen?: (value: boolean) => void;
|
||||
groupType?: GroupType;
|
||||
domPosition?: DOMRect;
|
||||
};
|
||||
|
||||
export type DropDownProp = {
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { capitalize, isEmpty } from 'lodash';
|
||||
import { capitalize, isEmpty, isNull } from 'lodash';
|
||||
import { EntityTags } from 'Models';
|
||||
import React, { FunctionComponent, useEffect, useRef, useState } from 'react';
|
||||
import { Button } from '../buttons/Button/Button';
|
||||
@ -43,6 +43,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
|
||||
const [hasFocus, setFocus] = useState<boolean>(false);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const node = useRef<HTMLDivElement>(null);
|
||||
const [inputDomRect, setInputDomRect] = useState<DOMRect>();
|
||||
// const [inputWidth, setInputWidth] = useState(INPUT_COLLAPED);
|
||||
// const [inputMinWidth, setInputMinWidth] = useState(INPUT_AUTO);
|
||||
|
||||
@ -64,6 +65,12 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!isNull(inputRef.current)) {
|
||||
setInputDomRect(inputRef.current.getBoundingClientRect());
|
||||
}
|
||||
}, [newTag]);
|
||||
|
||||
const getTagList = () => {
|
||||
const newTags = tagList
|
||||
.filter((tag) => {
|
||||
@ -227,6 +234,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
|
||||
{newTag && (
|
||||
<DropDownList
|
||||
horzPosRight
|
||||
domPosition={inputDomRect}
|
||||
dropDownList={getTagList()}
|
||||
searchString={newTag}
|
||||
onSelect={handleTagSelection}
|
||||
|
@ -0,0 +1,28 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
function getWindowDimensions() {
|
||||
const { innerWidth: width, innerHeight: height } = window;
|
||||
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
};
|
||||
}
|
||||
|
||||
export function useWindowDimensions() {
|
||||
const [windowDimensions, setWindowDimensions] = useState(
|
||||
getWindowDimensions()
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
function handleResize() {
|
||||
setWindowDimensions(getWindowDimensions());
|
||||
}
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
return windowDimensions;
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
const BUFFER_VALUE = 200;
|
||||
const GAP = 10;
|
||||
|
||||
export const getTopPosition = (
|
||||
windowHeight: number,
|
||||
bottomPosition: number,
|
||||
elementHeight: number
|
||||
) => {
|
||||
const bottomSpace = windowHeight - (bottomPosition + BUFFER_VALUE);
|
||||
|
||||
return bottomSpace < 0 ? { bottom: `${elementHeight + GAP}px` } : {};
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user