diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx index 4a4b9ab277c..2472573fcf9 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx @@ -18,6 +18,7 @@ import { SCHEMA } from '../../utils/slate'; import { useStyles2 } from '../../themes'; import { DataLinkBuiltInVars, GrafanaThemeV2, VariableOrigin, VariableSuggestion } from '@grafana/data'; import { getInputStyles } from '../Input/Input'; +import CustomScrollbar from '../CustomScrollbar/CustomScrollbar'; const modulo = (a: number, n: number) => a - n * Math.floor(a / n); @@ -81,6 +82,12 @@ export const DataLinkInput: React.FC = memo( const stateRef = useRef({ showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange }); stateRef.current = { showingSuggestions, suggestions, suggestionsIndex, linkUrl, onChange }; + // Used to get the height of the suggestion elements in order to scroll to them. + const activeRef = useRef(null); + const activeIndexPosition = useMemo(() => getElementPosition(activeRef.current, suggestionsIndex), [ + suggestionsIndex, + ]); + // SelectionReference is used to position the variables suggestion relatively to current DOM selection const selectionRef = useMemo(() => new SelectionReference(), []); @@ -172,12 +179,15 @@ export const DataLinkInput: React.FC = memo( {({ ref, style, placement }) => { return (
- setShowingSuggestions(false)} - activeIndex={suggestionsIndex} - /> + + setShowingSuggestions(false)} + activeIndex={suggestionsIndex} + /> +
); }} @@ -208,3 +218,7 @@ export const DataLinkInput: React.FC = memo( ); DataLinkInput.displayName = 'DataLinkInput'; + +function getElementPosition(suggestionElement: HTMLElement | null, activeIndex: number) { + return (suggestionElement?.clientHeight ?? 0) * activeIndex; +} diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx index 2743eca5898..b104309964f 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx @@ -7,6 +7,7 @@ import { List } from '../index'; import { useStyles2 } from '../../themes'; interface DataLinkSuggestionsProps { + activeRef?: React.RefObject; suggestions: VariableSuggestion[]; activeIndex: number; onSuggestionSelect: (suggestion: VariableSuggestion) => void; @@ -23,7 +24,6 @@ const getStyles = (theme: GrafanaThemeV2) => { `, wrapper: css` background: ${theme.colors.background.primary}; - z-index: 1; width: 250px; box-shadow: 0 5px 10px 0 ${theme.shadows.z1}; `, @@ -100,10 +100,11 @@ DataLinkSuggestions.displayName = 'DataLinkSuggestions'; interface DataLinkSuggestionsListProps extends DataLinkSuggestionsProps { label: string; activeIndexOffset: number; + activeRef?: React.RefObject; } const DataLinkSuggestionsList: React.FC = React.memo( - ({ activeIndex, activeIndexOffset, label, onClose, onSuggestionSelect, suggestions }) => { + ({ activeIndex, activeIndexOffset, label, onClose, onSuggestionSelect, suggestions, activeRef: selectedRef }) => { const styles = useStyles2(getStyles); return ( @@ -112,9 +113,11 @@ const DataLinkSuggestionsList: React.FC = React.me className={styles.list} items={suggestions} renderItem={(item, index) => { + const isActive = index + activeIndexOffset === activeIndex; return (
{ onSuggestionSelect(item); }}